Skip to content

Commit 0b305d2

Browse files
committed
[Feature] [Platform] Storage Debug
1 parent dd01c7b commit 0b305d2

File tree

26 files changed

+433
-61
lines changed

26 files changed

+433
-61
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ Flags:
204204
--kubernetes.qps float32 Number of queries per second for k8s API (default 32)
205205
--leader.label.skip Skips Leader Label for the Pod
206206
--log.format string Set log format. Allowed values: 'pretty', 'JSON'. If empty, default format is used (default "pretty")
207-
--log.level stringArray Set log levels in format <level> or <logger>=<level>. Possible loggers: action, agency, api-server, assertion, backup-operator, chaos-monkey, crd, deployment, deployment-ci, deployment-reconcile, deployment-replication, deployment-resilience, deployment-resources, deployment-storage, deployment-storage-pc, deployment-storage-service, generic-parent-operator, helm, http, inspector, integration-authn-v1, integration-config-v1, integration-envoy-auth-v3, integration-envoy-auth-v3-impl-auth-bearer, integration-envoy-auth-v3-impl-auth-cookie, integration-envoy-auth-v3-impl-custom-openid, integration-envoy-auth-v3-impl-pass-mode, integration-meta-v1, integration-scheduler-v2, integration-storage-v1-s3, integration-storage-v2, integrations, k8s-client, kubernetes, kubernetes-access, kubernetes-client, kubernetes-informer, monitor, networking-route-operator, operator, operator-arangojob-handler, operator-v2, operator-v2-event, operator-v2-worker, panics, platform-chart-operator, platform-pod-shutdown, platform-service-operator, platform-storage-operator, pod_compare, root, root-event-recorder, scheduler-batchjob-operator, scheduler-cronjob-operator, scheduler-deployment-operator, scheduler-pod-operator, scheduler-profile-operator, server, server-authentication, webhook (default [info])
207+
--log.level stringArray Set log levels in format <level> or <logger>=<level>. Possible loggers: action, agency, api-server, assertion, backup-operator, chaos-monkey, crd, deployment, deployment-ci, deployment-reconcile, deployment-replication, deployment-resilience, deployment-resources, deployment-storage, deployment-storage-pc, deployment-storage-service, generic-parent-operator, helm, http, inspector, integration-authn-v1, integration-config-v1, integration-envoy-auth-v3, integration-envoy-auth-v3-impl-auth-bearer, integration-envoy-auth-v3-impl-auth-cookie, integration-envoy-auth-v3-impl-custom-openid, integration-envoy-auth-v3-impl-pass-mode, integration-meta-v1, integration-scheduler-v2, integration-shutdown-v1, integration-storage-v1-s3, integration-storage-v2, integrations, k8s-client, kubernetes, kubernetes-access, kubernetes-client, kubernetes-informer, monitor, networking-route-operator, operator, operator-arangojob-handler, operator-v2, operator-v2-event, operator-v2-worker, panics, platform-chart-operator, platform-pod-shutdown, platform-service-operator, platform-storage-operator, pod_compare, root, root-event-recorder, scheduler-batchjob-operator, scheduler-cronjob-operator, scheduler-deployment-operator, scheduler-pod-operator, scheduler-profile-operator, server, server-authentication, webhook (default [info])
208208
--log.sampling If true, operator will try to minimize duplication of logging events (default true)
209209
--log.stdout If true, operator will log to the stdout (default true)
210210
--memory-limit uint Define memory limit for hard shutdown and the dump of goroutines. Used for testing

cmd/cmd.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ func Command() *cobra.Command {
282282
func Execute() int {
283283
flag.CommandLine.AddGoFlagSet(goflag.CommandLine)
284284

285-
if err := cmdMain.Execute(); err != nil {
285+
if err := cmdMain.ExecuteContext(shutdown.Context()); err != nil {
286286
var v cli.CommandExitCode
287287
if errors.As(err, &v) {
288288
return v.ExitCode

cmd/cmd_ops.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
flag "github.com/spf13/pflag"
2828

2929
"github.com/arangodb/kube-arangodb/pkg/util/cli"
30+
"github.com/arangodb/kube-arangodb/pkg/util/shutdown"
3031
)
3132

3233
var (
@@ -43,7 +44,7 @@ func CommandOps() *cobra.Command {
4344
func ExecuteOps() int {
4445
flag.CommandLine.AddGoFlagSet(goflag.CommandLine)
4546

46-
if err := cmdOps.Execute(); err != nil {
47+
if err := cmdOps.ExecuteContext(shutdown.Context()); err != nil {
4748
return 1
4849
}
4950

cmd/integration/init.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828

2929
integrations "github.com/arangodb/kube-arangodb/pkg/integrations"
3030
"github.com/arangodb/kube-arangodb/pkg/util/cli"
31+
"github.com/arangodb/kube-arangodb/pkg/util/shutdown"
3132
)
3233

3334
var (
@@ -51,7 +52,7 @@ func Command() *cobra.Command {
5152
func Execute() int {
5253
flag.CommandLine.AddGoFlagSet(goflag.CommandLine)
5354

54-
if err := cmd.Execute(); err != nil {
55+
if err := cmd.ExecuteContext(shutdown.Context()); err != nil {
5556
return 1
5657
}
5758

cmd/main-platform/main_int.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"github.com/arangodb/kube-arangodb/pkg/logging"
2828
"github.com/arangodb/kube-arangodb/pkg/platform"
2929
"github.com/arangodb/kube-arangodb/pkg/util/cli"
30+
"github.com/arangodb/kube-arangodb/pkg/util/shutdown"
3031
)
3132

3233
func main() {
@@ -50,7 +51,7 @@ func mainE() error {
5051
return err
5152
}
5253

53-
if err := c.Execute(); err != nil {
54+
if err := c.ExecuteContext(shutdown.Context()); err != nil {
5455
return err
5556
}
5657

docs/cli/arangodb_operator.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ Flags:
8686
--kubernetes.qps float32 Number of queries per second for k8s API (default 32)
8787
--leader.label.skip Skips Leader Label for the Pod
8888
--log.format string Set log format. Allowed values: 'pretty', 'JSON'. If empty, default format is used (default "pretty")
89-
--log.level stringArray Set log levels in format <level> or <logger>=<level>. Possible loggers: action, agency, api-server, assertion, backup-operator, chaos-monkey, crd, deployment, deployment-ci, deployment-reconcile, deployment-replication, deployment-resilience, deployment-resources, deployment-storage, deployment-storage-pc, deployment-storage-service, generic-parent-operator, helm, http, inspector, integration-authn-v1, integration-config-v1, integration-envoy-auth-v3, integration-envoy-auth-v3-impl-auth-bearer, integration-envoy-auth-v3-impl-auth-cookie, integration-envoy-auth-v3-impl-custom-openid, integration-envoy-auth-v3-impl-pass-mode, integration-meta-v1, integration-scheduler-v2, integration-storage-v1-s3, integration-storage-v2, integrations, k8s-client, kubernetes, kubernetes-access, kubernetes-client, kubernetes-informer, monitor, networking-route-operator, operator, operator-arangojob-handler, operator-v2, operator-v2-event, operator-v2-worker, panics, platform-chart-operator, platform-pod-shutdown, platform-service-operator, platform-storage-operator, pod_compare, root, root-event-recorder, scheduler-batchjob-operator, scheduler-cronjob-operator, scheduler-deployment-operator, scheduler-pod-operator, scheduler-profile-operator, server, server-authentication, webhook (default [info])
89+
--log.level stringArray Set log levels in format <level> or <logger>=<level>. Possible loggers: action, agency, api-server, assertion, backup-operator, chaos-monkey, crd, deployment, deployment-ci, deployment-reconcile, deployment-replication, deployment-resilience, deployment-resources, deployment-storage, deployment-storage-pc, deployment-storage-service, generic-parent-operator, helm, http, inspector, integration-authn-v1, integration-config-v1, integration-envoy-auth-v3, integration-envoy-auth-v3-impl-auth-bearer, integration-envoy-auth-v3-impl-auth-cookie, integration-envoy-auth-v3-impl-custom-openid, integration-envoy-auth-v3-impl-pass-mode, integration-meta-v1, integration-scheduler-v2, integration-shutdown-v1, integration-storage-v1-s3, integration-storage-v2, integrations, k8s-client, kubernetes, kubernetes-access, kubernetes-client, kubernetes-informer, monitor, networking-route-operator, operator, operator-arangojob-handler, operator-v2, operator-v2-event, operator-v2-worker, panics, platform-chart-operator, platform-pod-shutdown, platform-service-operator, platform-storage-operator, pod_compare, root, root-event-recorder, scheduler-batchjob-operator, scheduler-cronjob-operator, scheduler-deployment-operator, scheduler-pod-operator, scheduler-profile-operator, server, server-authentication, webhook (default [info])
9090
--log.sampling If true, operator will try to minimize duplication of logging events (default true)
9191
--log.stdout If true, operator will log to the stdout (default true)
9292
--memory-limit uint Define memory limit for hard shutdown and the dump of goroutines. Used for testing

docs/cli/arangodb_operator_integration.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ Flags:
7474
--integration.scheduler.v2.internal Defines if Internal access to service scheduler.v2 is enabled (Env: INTEGRATION_SCHEDULER_V2_INTERNAL) (default true)
7575
--integration.scheduler.v2.namespace string Kubernetes Namespace (Env: INTEGRATION_SCHEDULER_V2_NAMESPACE) (default "default")
7676
--integration.shutdown.v1 ShutdownV1 Handler (Env: INTEGRATION_SHUTDOWN_V1)
77+
--integration.shutdown.v1.debug.enabled Defines if debug extension is enabled (Env: INTEGRATION_SHUTDOWN_V1_DEBUG_ENABLED)
78+
--integration.shutdown.v1.debug.path string Path of the Debug Directory (Env: INTEGRATION_SHUTDOWN_V1_DEBUG_PATH) (default "/debug")
79+
--integration.shutdown.v1.debug.timeout duration Timeout of the Debug action (Env: INTEGRATION_SHUTDOWN_V1_DEBUG_TIMEOUT) (default 1m0s)
7780
--integration.shutdown.v1.external Defines if External access to service shutdown.v1 is enabled (Env: INTEGRATION_SHUTDOWN_V1_EXTERNAL)
7881
--integration.shutdown.v1.internal Defines if Internal access to service shutdown.v1 is enabled (Env: INTEGRATION_SHUTDOWN_V1_INTERNAL) (default true)
7982
--integration.storage.v2 StorageBucket V2 Integration (Env: INTEGRATION_STORAGE_V2)

docs/integration-sidecar.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ Integration Sidecar is supported in a few resources managed by Operator:
1919
- ArangoSchedulerCronJob (scheduler.arangodb.com/v1beta1)
2020
- ArangoSchedulerPod (scheduler.arangodb.com/v1beta1)
2121

22+
S tandard Kubernetes Resources (like Pod) are also supported with Webhook extension is enabled.
23+
2224
To enable integration sidecar for specific deployment label needs to be defined:
2325

2426
```yaml
@@ -97,6 +99,9 @@ To enable:
9799
metadata:
98100
labels:
99101
integration.profiles.arangodb.com/storage: v1
102+
103+
# Optionally, enable DebugPackage integration
104+
storage.integration.profiles.arangodb.com/debug: "enabled"
100105
```
101106
102107
#### [Storage V2](./integration/storage.v2.md)

docs/integration/shutdown.v1.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,15 @@ spec:
3131
```
3232
3333
Pod will receive shutdown request on port `port1` if containers `app` and `app2` will be in non running state.
34+
35+
## Extensions
36+
37+
### DebugPackage PreShutdown Hook
38+
39+
Example:
40+
41+
```yaml
42+
metadata:
43+
labels:
44+
core.shutdown.arangodb.com/app: "wait"
45+
```
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2025 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
21+
package v1
22+
23+
import "time"
24+
25+
type Configuration struct {
26+
Debug ConfigurationDebug `json:"debug,omitempty"`
27+
}
28+
29+
type ConfigurationDebug struct {
30+
Enabled bool `json:"enabled,omitempty"`
31+
32+
Path string `json:"path,omitempty"`
33+
34+
Timeout time.Duration `json:"timeout,omitempty"`
35+
}

integrations/shutdown/v1/impl.go

Lines changed: 85 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,34 @@ package v1
2222

2323
import (
2424
"context"
25+
"io/fs"
26+
"path/filepath"
27+
goStrings "strings"
2528
"time"
2629

2730
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
2831
"google.golang.org/grpc"
2932

3033
pbSharedV1 "github.com/arangodb/kube-arangodb/integrations/shared/v1/definition"
3134
pbShutdownV1 "github.com/arangodb/kube-arangodb/integrations/shutdown/v1/definition"
35+
pbStorageV2 "github.com/arangodb/kube-arangodb/integrations/storage/v2/definition"
36+
"github.com/arangodb/kube-arangodb/pkg/util/closer"
37+
"github.com/arangodb/kube-arangodb/pkg/util/constants"
38+
"github.com/arangodb/kube-arangodb/pkg/util/errors"
39+
ugrpc "github.com/arangodb/kube-arangodb/pkg/util/grpc"
40+
"github.com/arangodb/kube-arangodb/pkg/util/shutdown"
3241
"github.com/arangodb/kube-arangodb/pkg/util/svc"
3342
)
3443

35-
func New(closer context.CancelFunc) svc.Handler {
36-
return &impl{closer: closer}
44+
func New(cfg Configuration, c context.CancelFunc) svc.Handler {
45+
var z = &impl{
46+
closer: c,
47+
cfg: cfg,
48+
}
49+
50+
z.close = closer.CloseOnce(z)
51+
52+
return z
3753
}
3854

3955
var _ pbShutdownV1.ShutdownV1Server = &impl{}
@@ -42,9 +58,71 @@ var _ svc.Handler = &impl{}
4258
type impl struct {
4359
pbShutdownV1.UnimplementedShutdownV1Server
4460

61+
cfg Configuration
62+
63+
close closer.Close
64+
4565
closer context.CancelFunc
4666
}
4767

68+
func (i *impl) Close() error {
69+
defer i.closer()
70+
71+
ctx, c := context.WithTimeout(shutdown.Context(), i.cfg.Debug.Timeout)
72+
defer c()
73+
74+
time.Sleep(50 * time.Millisecond)
75+
76+
if i.cfg.Debug.Enabled {
77+
logger.Info("Enforce Debug collection")
78+
79+
// Need to fetch Debug Details
80+
if addr, ok := constants.INTEGRATION_SERVICE_ADDRESS.Lookup(); ok {
81+
client, close, err := ugrpc.NewGRPCClient(ctx, pbStorageV2.NewStorageV2Client, addr)
82+
if err != nil {
83+
return err
84+
}
85+
86+
defer close.Close()
87+
88+
if err := filepath.Walk(i.cfg.Debug.Path, func(path string, info fs.FileInfo, err error) error {
89+
logger := logger.Str("file", path)
90+
if info.IsDir() {
91+
logger.Info("Skip Directory")
92+
return nil
93+
}
94+
95+
if info.Size() == 0 {
96+
logger.Info("Skip Empty File")
97+
return nil
98+
}
99+
100+
logger = logger.Int64("size", info.Size())
101+
102+
k := goStrings.TrimPrefix(path, i.cfg.Debug.Path)
103+
104+
logger.Str("key", k).Info("Sync file")
105+
106+
if _, err := pbStorageV2.SendFile(ctx, client, k, path); err != nil {
107+
logger.Err(err).Warn("Failed to send file to server for DebugPackage")
108+
} else {
109+
logger.Info("Send Completed")
110+
}
111+
112+
return nil
113+
}); err != nil {
114+
return err
115+
}
116+
} else {
117+
return errors.Errorf("Address of the Service not defined")
118+
}
119+
} else {
120+
logger.Info("Skip Debug collection")
121+
}
122+
123+
return nil
124+
}
125+
48126
func (i *impl) Name() string {
49127
return pbShutdownV1.Name
50128
}
@@ -63,10 +141,12 @@ func (i *impl) Gateway(ctx context.Context, mux *runtime.ServeMux) error {
63141

64142
func (i *impl) Shutdown(ctx context.Context, empty *pbSharedV1.Empty) (*pbSharedV1.Empty, error) {
65143
go func() {
66-
defer i.closer()
67-
68-
time.Sleep(50 * time.Millisecond)
144+
if err := i.close.Close(); err != nil {
145+
logger.Err(err).Warn("Shutting down failed")
146+
}
69147
}()
70148

149+
logger.Info("Shutting down")
150+
71151
return &pbSharedV1.Empty{}, nil
72152
}

integrations/shutdown/v1/impl_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ func Test_ShutdownGRPC(t *testing.T) {
4040

4141
local, err := svc.NewService(svc.Configuration{
4242
Address: "127.0.0.1:0",
43-
}, New(c))
43+
}, New(Configuration{}, c))
4444
require.NoError(t, err)
4545

4646
start := local.Start(ctx)

integrations/shutdown/v1/logger.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2025 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
21+
package v1
22+
23+
import "github.com/arangodb/kube-arangodb/pkg/logging"
24+
25+
var logger = logging.Global().RegisterAndGetLogger("integration-shutdown-v1", logging.Info)

integrations/shutdown/v1/service_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import (
3737
func Client(t *testing.T, ctx context.Context, c context.CancelFunc) pbShutdownV1.ShutdownV1Client {
3838
local, err := svc.NewService(svc.Configuration{
3939
Address: "127.0.0.1:0",
40-
}, New(c))
40+
}, New(Configuration{}, c))
4141
require.NoError(t, err)
4242

4343
start := local.Start(ctx)

integrations/storage/v2/definition/helpers.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ package definition
2323
import (
2424
"context"
2525
"io"
26+
"os"
2627

2728
"github.com/arangodb/kube-arangodb/pkg/util"
2829
"github.com/arangodb/kube-arangodb/pkg/util/errors"
@@ -31,6 +32,24 @@ import (
3132

3233
const BufferSize = 4094
3334

35+
func SendFile(ctx context.Context, client StorageV2Client, key string, path string) (*StorageV2WriteObjectResponse, error) {
36+
f, err := os.Open(path)
37+
if err != nil {
38+
return nil, err
39+
}
40+
41+
p, err := Send(ctx, client, key, f)
42+
if err != nil {
43+
if cerr := f.Close(); cerr != nil {
44+
return nil, cerr
45+
}
46+
47+
return nil, err
48+
}
49+
50+
return p, nil
51+
}
52+
3453
func Send(ctx context.Context, client StorageV2Client, key string, in io.Reader) (*StorageV2WriteObjectResponse, error) {
3554
cache := make([]byte, BufferSize)
3655

0 commit comments

Comments
 (0)