Skip to content
Closed
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
38 changes: 19 additions & 19 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,22 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
with:
persist-credentials: false
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
- uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
with:
go-version-file: go.mod
cache: false
- name: Check approved Go release line
run: go env GOVERSION | grep -Eq '^go1\.26\.[0-9]+$'
- name: golangci-lint
uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0
uses: golangci/golangci-lint-action@ba0d7d2ec06a0ea1cb5fa41b2e4a3ab91d21278a # v9.3.0
with:
# Require: The version of golangci-lint to use.
# When `install-mode` is `binary` (default) the value can be v1.2 or v1.2.3 or `latest` to use the latest version.
# When `install-mode` is `goinstall` the value can be v1.2.3, `latest`, or the hash of a commit.
version: v2.11.3
version: v2.14.0

check-license:
name: License scan
Expand All @@ -58,10 +58,10 @@ jobs:
REPORT_FILE: gl-license-scanning-report.json

steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
with:
persist-credentials: false
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
- uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
with:
go-version-file: go.mod
cache: false
Expand All @@ -73,7 +73,7 @@ jobs:
run: |
go-licenses report . > licenses.csv
- name: Save license scan report
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: license_scanning
path: licenses.csv
Expand All @@ -86,15 +86,15 @@ jobs:
contents: read

steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
with:
persist-credentials: false
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
- uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
with:
go-version-file: go.mod
cache: false
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@5daf1e915a5f0af01ddbcd89a43b8061ff4f1a89 # v7.2.2
uses: goreleaser/goreleaser-action@a4f02ab5355a589de60d917a659ce617ed19b3de # v7.3.0
with:
# either 'goreleaser' (default) or 'goreleaser-pro'
distribution: goreleaser
Expand All @@ -112,10 +112,10 @@ jobs:
contents: read

steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
with:
persist-credentials: false
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
- uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
with:
go-version-file: go.mod
cache: false
Expand All @@ -132,10 +132,10 @@ jobs:
GOVULNCHECK_VERSION: v1.6.0

steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
with:
persist-credentials: false
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
- uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
with:
go-version-file: go.mod
cache: false
Expand All @@ -148,7 +148,7 @@ jobs:
- name: Test that the symbol-table guard rejects a stripped binary
run: scripts/assert-go-symbols-test.sh
- name: Build GoReleaser snapshot artifacts
uses: goreleaser/goreleaser-action@5daf1e915a5f0af01ddbcd89a43b8061ff4f1a89 # v7.2.2
uses: goreleaser/goreleaser-action@a4f02ab5355a589de60d917a659ce617ed19b3de # v7.3.0
with:
distribution: goreleaser
version: v1.25.1
Expand All @@ -169,7 +169,7 @@ jobs:
upload-sarif: "false"
- name: Upload security evidence
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: release-artifact-security
path: |
Expand All @@ -193,15 +193,15 @@ jobs:
S3_BUCKET: "s3://cli-dl.stackstate.com/stackstate-backup-cli/"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
with:
persist-credentials: false
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
- uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
with:
go-version-file: go.mod
cache: false
- name: Go releaser publish
uses: goreleaser/goreleaser-action@5daf1e915a5f0af01ddbcd89a43b8061ff4f1a89 # v7.2.2
uses: goreleaser/goreleaser-action@a4f02ab5355a589de60d917a659ce617ed19b3de # v7.3.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/renovate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
permission-checks: read
permission-statuses: read
- name: Run Renovate
uses: renovatebot/github-action@8217b3fc286df088d7c27f3255fe8414463bc0fd # v46.1.15
uses: renovatebot/github-action@f0f41e5f2e706165f6814b1d0f0d0e319de7d1d9 # v46.3.8
with:
token: ${{ steps.app-token.outputs.token }}
env:
Expand Down
2 changes: 2 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ linters:
funlen:
lines: 100
statements: 60
goconst:
ignore-tests: true
lll:
line-length: 250
mnd:
Expand Down
2 changes: 1 addition & 1 deletion cmd/settings/check_and_finalize.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func runCheckAndFinalize(appCtx *app.Context) error {
K8sClient: appCtx.K8sClient,
Namespace: appCtx.Namespace,
JobName: checkJobName,
ServiceName: "settings",
ServiceName: settingsName,
ScaleUpFn: scale.ScaleUpAndReleaseLock,
ScaleDownFn: scale.ScaleDown,
ScaleSelector: appCtx.Config.Settings.Restore.ScaleDownLabelSelector,
Expand Down
2 changes: 1 addition & 1 deletion cmd/settings/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ func buildVolumes(config *config.Config, defaultMode int32) []corev1.Volume {
// buildContainers constructs containers for the restore job
func buildContainer(envVar []corev1.EnvVar, command []string, config *config.Config) corev1.Container {
return corev1.Container{
Name: "settings",
Name: settingsName,
Image: config.Settings.Restore.Job.Image,
ImagePullPolicy: corev1.PullIfNotPresent,
SecurityContext: k8s.ConvertSecurityContext(config.Settings.Restore.Job.ContainerSecurityContext),
Expand Down
4 changes: 3 additions & 1 deletion cmd/settings/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import (
"github.com/stackvista/stackstate-backup-cli/internal/foundation/config"
)

const settingsName = config.DatastoreSettings

func Cmd(globalFlags *config.CLIGlobalFlags) *cobra.Command {
cmd := &cobra.Command{
Use: "settings",
Use: settingsName,
Short: "Settings backup and restore operations",
}

Expand Down
15 changes: 9 additions & 6 deletions cmd/stackgraphv2/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ const (
restoreNameTemplate = "stackgraph-v2-restore"
configMapDefaultFileMode = 0755
purgeStackgraphDataFlag = "-force"
backupLogVolume = "backup-log"
restoreScriptsVolume = "backup-restore-scripts"
minioKeysVolume = "minio-keys"
)

// Restore command flags
Expand Down Expand Up @@ -306,9 +309,9 @@ func buildRestoreEnvVars(backupFile string, config *config.Config) []corev1.EnvV
// buildRestoreVolumeMounts constructs volume mounts for the restore job container
func buildRestoreVolumeMounts(config *config.Config) []corev1.VolumeMount {
volumeMounts := []corev1.VolumeMount{
{Name: "backup-log", MountPath: "/opt/docker/etc_log"},
{Name: "backup-restore-scripts", MountPath: "/backup-restore-scripts"},
{Name: "minio-keys", MountPath: "/aws-keys"},
{Name: backupLogVolume, MountPath: "/opt/docker/etc_log"},
{Name: restoreScriptsVolume, MountPath: "/backup-restore-scripts"},
{Name: minioKeysVolume, MountPath: "/aws-keys"},
{Name: "tmp-data", MountPath: "/tmp-data"},
}

Expand Down Expand Up @@ -344,7 +347,7 @@ func buildRestoreInitContainers(config *config.Config) []corev1.Container {
func buildRestoreVolumes(jobName string, config *config.Config, defaultMode int32) []corev1.Volume {
volumes := []corev1.Volume{
{
Name: "backup-log",
Name: backupLogVolume,
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Expand All @@ -354,7 +357,7 @@ func buildRestoreVolumes(jobName string, config *config.Config, defaultMode int3
},
},
{
Name: "backup-restore-scripts",
Name: restoreScriptsVolume,
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Expand All @@ -365,7 +368,7 @@ func buildRestoreVolumes(jobName string, config *config.Config, defaultMode int3
},
},
{
Name: "minio-keys",
Name: minioKeysVolume,
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
SecretName: restore.MinioKeysSecretName,
Expand Down
12 changes: 6 additions & 6 deletions cmd/stackgraphv2/simplejob.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ func buildSimpleJobEnvVars(config *config.Config) []corev1.EnvVar {
// buildSimpleJobVolumeMounts constructs volume mounts shared by the abort and backfill job containers
func buildSimpleJobVolumeMounts() []corev1.VolumeMount {
return []corev1.VolumeMount{
{Name: "backup-log", MountPath: "/opt/docker/etc_log"},
{Name: "backup-restore-scripts", MountPath: "/backup-restore-scripts"},
{Name: "minio-keys", MountPath: "/aws-keys"},
{Name: backupLogVolume, MountPath: "/opt/docker/etc_log"},
{Name: restoreScriptsVolume, MountPath: "/backup-restore-scripts"},
{Name: minioKeysVolume, MountPath: "/aws-keys"},
}
}

Expand All @@ -86,7 +86,7 @@ func buildSimpleJobInitContainers(config *config.Config) []corev1.Container {
func buildSimpleJobVolumes(config *config.Config, defaultMode int32) []corev1.Volume {
return []corev1.Volume{
{
Name: "backup-log",
Name: backupLogVolume,
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Expand All @@ -96,7 +96,7 @@ func buildSimpleJobVolumes(config *config.Config, defaultMode int32) []corev1.Vo
},
},
{
Name: "backup-restore-scripts",
Name: restoreScriptsVolume,
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Expand All @@ -107,7 +107,7 @@ func buildSimpleJobVolumes(config *config.Config, defaultMode int32) []corev1.Vo
},
},
{
Name: "minio-keys",
Name: minioKeysVolume,
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
SecretName: restore.MinioKeysSecretName,
Expand Down
15 changes: 9 additions & 6 deletions internal/orchestration/replication/applicability.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ import (
)

const (
hdfsComponent = "hdfs"
clickhouseComponent = "clickhouse"
nameNodeComponent = "hdfs-nn"
dataNodeComponent = "hdfs-dn"
monoComponent = "stackgraph"
hdfsComponent = "hdfs"
clickhouseComponent = "clickhouse"
elasticsearchComponent = "elasticsearch"
kafkaComponent = "kafka"
zookeeperComponent = "zookeeper"
nameNodeComponent = "hdfs-nn"
dataNodeComponent = "hdfs-dn"
monoComponent = "stackgraph"
)

func workloadComponent(workload appsv1.StatefulSet) string {
Expand All @@ -26,7 +29,7 @@ func workloadComponent(workload appsv1.StatefulSet) string {
}
}
switch name {
case "elasticsearch", clickhouseComponent, "kafka", "zookeeper":
case elasticsearchComponent, clickhouseComponent, kafkaComponent, zookeeperComponent:
return name
default:
return ""
Expand Down
17 changes: 11 additions & 6 deletions internal/orchestration/replication/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ import (
"time"
)

const requestTimeout = 30 * time.Second
const (
requestTimeout = 30 * time.Second
bashBinary = "bash"
bashFlags = "-ec"
replicationQueryName = "replication-check"
)

// Checker observes databases without invoking backup or restore operations.
type Checker struct {
Expand Down Expand Up @@ -83,15 +88,15 @@ func (c *Checker) query(ctx context.Context, pod, container string, command []st

func (c *Checker) checkComponent(ctx context.Context, inventory inventory, component string) Result {
switch component {
case "hdfs":
case hdfsComponent:
return c.checkHDFS(ctx, inventory)
case "elasticsearch":
case elasticsearchComponent:
return c.checkElasticsearch(ctx, inventory)
case "kafka":
case kafkaComponent:
return c.checkKafka(ctx, inventory)
case "clickhouse":
case clickhouseComponent:
return c.checkClickHouse(ctx, inventory)
case "zookeeper":
case zookeeperComponent:
return c.checkZooKeeper(ctx, inventory)
default:
return result(component, Unknown, "unsupported component")
Expand Down
6 changes: 3 additions & 3 deletions internal/orchestration/replication/clickhouse.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func (c *Checker) checkClickHouse(ctx context.Context, inventory inventory) Resu
if member.replicas < minReplicas {
return result("clickhouse", Degraded, fmt.Sprintf("%s belongs to a shard with fewer than two replicas", member.pod.Name))
}
command := []string{"bash", "-ec", clickhouseQuery, "replication-check", clickhouseSQL}
command := []string{bashBinary, bashFlags, clickhouseQuery, replicationQueryName, clickhouseSQL}
data, err := c.query(ctx, member.pod.Name, "clickhouse", command)
if err != nil {
return result("clickhouse", Unknown, err.Error())
Expand All @@ -67,7 +67,7 @@ func (c *Checker) verifyEmptyLogs(ctx context.Context, pod string, rows []replic
if !rows[n].needsLogVerification {
continue
}
command := []string{"bash", "-ec", clickhouseQuery, "replication-check", clickhouseEmptyLogSQL, "--param_log_path=" + rows[n].path + "/log"}
command := []string{bashBinary, bashFlags, clickhouseQuery, replicationQueryName, clickhouseEmptyLogSQL, "--param_log_path=" + rows[n].path + "/log"}
data, err := c.query(ctx, pod, "clickhouse", command)
if err != nil {
return fmt.Errorf("%s: could not verify empty replication log: %w", pod, err)
Expand Down Expand Up @@ -178,7 +178,7 @@ func evaluateClickHouse(observations []replicaObservation) Result {
}
if len(problems) > 0 {
sort.Strings(problems)
return Result{Component: "clickhouse", Status: Degraded, Messages: problems}
return Result{Component: clickhouseComponent, Status: Degraded, Messages: problems}
}
report := result("clickhouse", Healthy, fmt.Sprintf("%d replicated table groups checked on every member; no pending data replication tasks", len(groups)))
if historicalErrors > 0 {
Expand Down
4 changes: 2 additions & 2 deletions internal/orchestration/replication/elasticsearch.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func (c *Checker) checkElasticsearch(ctx context.Context, inventory inventory) R
if err := expectedMembers(members); err != nil {
return result("elasticsearch", Degraded, err.Error())
}
command := []string{"bash", "-ec", elasticsearchQuery}
command := []string{bashBinary, bashFlags, elasticsearchQuery}
data, err := c.query(ctx, members[0].pod.Name, "elasticsearch", command)
if err != nil {
return result("elasticsearch", Unknown, err.Error())
Expand Down Expand Up @@ -66,7 +66,7 @@ func evaluateElasticsearch(data []byte, expected int) Result {
}
if len(problems) > 0 {
sort.Strings(problems)
return Result{Component: "elasticsearch", Status: Degraded, Messages: problems}
return Result{Component: elasticsearchComponent, Status: Degraded, Messages: problems}
}
return result("elasticsearch", Healthy, fmt.Sprintf("%d indices have replica shards; all shards allocated with no recovery or relocation", len(indices)))
}
4 changes: 2 additions & 2 deletions internal/orchestration/replication/hdfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func (c *Checker) checkHDFS(ctx context.Context, inventory inventory) Result {
if err := expectedMembers(datanodes); err != nil {
return result("hdfs", Degraded, err.Error())
}
data, err := c.query(ctx, namenodes[0].pod.Name, "namenode", []string{"bash", "-ec", hdfsQuery})
data, err := c.query(ctx, namenodes[0].pod.Name, "namenode", []string{bashBinary, bashFlags, hdfsQuery})
if err != nil {
return result("hdfs", Unknown, err.Error())
}
Expand Down Expand Up @@ -85,7 +85,7 @@ func evaluateHDFS(data []byte, expected int) Result {
}
}
if len(problems) > 0 {
return Result{Component: "hdfs", Status: Degraded, Messages: problems}
return Result{Component: hdfsComponent, Status: Degraded, Messages: problems}
}
return result("hdfs", Healthy, fmt.Sprintf("%d DataNodes live; no missing, corrupt, under-replicated or pending-replication blocks", expected))
}
Loading
Loading