1
0
Fork 0
mirror of https://github.com/arangodb/kube-arangodb.git synced 2024-12-14 11:57:37 +00:00

[Feature] Extract Integration Service (#1591)

This commit is contained in:
Adam Janikowski 2024-02-12 13:22:15 +01:00 committed by GitHub
parent 61cdd68e89
commit 6ea6950e9e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 743 additions and 259 deletions

View file

@ -49,6 +49,14 @@ linters-settings:
alias: mlSharedTests
- pkg: github.com/arangodb/kube-arangodb/pkg/apis/ml/v1alpha1
alias: mlApi
- pkg: github.com/arangodb/kube-arangodb/integrations/shutdown/v1/definition
alias: pbShutdownV1
- pkg: github.com/arangodb/kube-arangodb/integrations/shutdown/v1
alias: pbImplShutdownV1
- pkg: github.com/arangodb/kube-arangodb/integrations/shared/v1/definition
alias: pbSharedV1
- pkg: github.com/arangodb/kube-arangodb/integrations/shared/v1
alias: pbImplSharedV1
gci:
sections:
- standard

View file

@ -2,6 +2,7 @@
## [master](https://github.com/arangodb/kube-arangodb/tree/master) (N/A)
- (Feature) Extract GRPC Server
- (Feature) Extract Integration Service
## [1.2.37](https://github.com/arangodb/kube-arangodb/tree/1.2.37) (2024-01-22)
- (Documentation) Improve documentation rendering for GitHub Pages

View file

@ -1,7 +1,7 @@
//
// DISCLAIMER
//
// Copyright 2023 ArangoDB GmbH, Cologne, Germany
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -20,20 +20,10 @@
package cmd
import (
"github.com/spf13/cobra"
)
var (
cmdML = &cobra.Command{
Use: "ml",
Run: func(cmd *cobra.Command, args []string) {
},
Hidden: true,
}
)
import "github.com/arangodb/kube-arangodb/cmd/integrations"
func init() {
cmdMain.AddCommand(cmdML)
if err := integrations.Register(&cmdMain); err != nil {
panic(err.Error())
}
}

View file

@ -0,0 +1,42 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package integrations
import (
"context"
"github.com/spf13/cobra"
"github.com/arangodb/kube-arangodb/pkg/util/svc"
)
type Factory func() Integration
type ArgGen func(name string) string
type Integration interface {
Name() string
Description() string
Register(cmd *cobra.Command, arg ArgGen) error
Handler(ctx context.Context) (svc.Handler, error)
}

View file

@ -0,0 +1,31 @@
//
// DISCLAIMER
//
// Copyright 2016-2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package integrations
import (
"time"
"github.com/arangodb/kube-arangodb/pkg/logging"
)
var (
logger = logging.Global().RegisterAndGetLogger("integrations", logging.Info, logging.WithSamplingPeriod(time.Second*10))
)

View file

@ -0,0 +1,142 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package integrations
import (
"fmt"
"sort"
"sync"
"github.com/spf13/cobra"
"github.com/arangodb/kube-arangodb/pkg/util/errors"
"github.com/arangodb/kube-arangodb/pkg/util/shutdown"
"github.com/arangodb/kube-arangodb/pkg/util/svc"
)
var (
lock sync.Mutex
registered []Factory
)
func register(i Factory) {
lock.Lock()
defer lock.Unlock()
registered = append(registered, i)
}
func Register(cmd *cobra.Command) error {
var c configuration
return c.Register(cmd)
}
type configuration struct {
registered []Integration
health struct {
shutdownEnabled bool
config svc.Configuration
}
services struct {
config svc.Configuration
}
}
func (c *configuration) Register(cmd *cobra.Command) error {
lock.Lock()
defer lock.Unlock()
c.registered = make([]Integration, len(registered))
for id := range registered {
c.registered[id] = registered[id]()
}
sort.Slice(c.registered, func(i, j int) bool {
return c.registered[i].Name() < c.registered[j].Name()
})
subCommand := &cobra.Command{
Use: "integration",
RunE: c.run,
}
f := subCommand.Flags()
f.StringVar(&c.health.config.Address, "health.address", "0.0.0.0:9091", "Address to expose health service")
f.BoolVar(&c.health.shutdownEnabled, "health.shutdown.enabled", true, "Determines if shutdown service should be enabled and exposed")
f.StringVar(&c.services.config.Address, "services.address", "127.0.0.1:9092", "Address to expose services")
for _, service := range c.registered {
prefix := fmt.Sprintf("integration.%s", service.Name())
f.Bool(prefix, false, service.Description())
if err := service.Register(subCommand, func(name string) string {
return fmt.Sprintf("%s.%s", prefix, name)
}); err != nil {
return errors.Wrapf(err, "Unable to register service %s", service.Name())
}
}
cmd.AddCommand(subCommand)
return nil
}
func (c *configuration) run(cmd *cobra.Command, args []string) error {
handlers := make([]svc.Handler, 0, len(c.registered))
for _, handler := range c.registered {
if ok, err := cmd.Flags().GetBool(fmt.Sprintf("integration.%s", handler.Name())); err != nil {
return err
} else {
logger.Str("service", handler.Name()).Bool("enabled", ok).Info("Service discovered")
if ok {
if svc, err := handler.Handler(shutdown.Context()); err != nil {
return err
} else {
handlers = append(handlers, svc)
}
}
}
}
var healthServices []svc.Handler
if c.health.shutdownEnabled {
healthServices = append(healthServices, shutdown.NewGlobalShutdownServer())
}
health := svc.NewHealthService(c.health.config, svc.Readiness, healthServices...)
healthHandler := health.Start(shutdown.Context())
logger.Str("address", healthHandler.Address()).Info("Health handler started")
s := svc.NewService(c.services.config, handlers...).StartWithHealth(shutdown.Context(), health)
logger.Str("address", s.Address()).Info("Service handler started")
return s.Wait()
}

View file

@ -0,0 +1,56 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package integrations
import (
"context"
"github.com/spf13/cobra"
pbImplShutdownV1 "github.com/arangodb/kube-arangodb/integrations/shutdown/v1"
"github.com/arangodb/kube-arangodb/pkg/util/shutdown"
"github.com/arangodb/kube-arangodb/pkg/util/svc"
)
func init() {
register(func() Integration {
return &shutdownV1{}
})
}
type shutdownV1 struct {
}
func (s *shutdownV1) Handler(ctx context.Context) (svc.Handler, error) {
return shutdown.NewGlobalShutdownServer(), nil
}
func (s *shutdownV1) Name() string {
return pbImplShutdownV1.Name
}
func (s *shutdownV1) Description() string {
return "ShutdownV1 Handler"
}
func (s *shutdownV1) Register(cmd *cobra.Command, arg ArgGen) error {
return nil
}

View file

@ -0,0 +1,69 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package integrations
import (
"context"
"github.com/spf13/cobra"
"github.com/arangodb/kube-arangodb/pkg/ml/storage"
"github.com/arangodb/kube-arangodb/pkg/util/svc"
)
func init() {
register(func() Integration {
return &storageV1{}
})
}
type storageV1 struct {
Configuration storage.Configuration
}
func (b *storageV1) Name() string {
return "storage.v1"
}
func (b *storageV1) Description() string {
return "StorageBucket Integration"
}
func (b *storageV1) Register(cmd *cobra.Command, arg ArgGen) error {
f := cmd.Flags()
f.StringVar((*string)(&b.Configuration.Type), arg("type"), string(storage.S3), "Type of the Storage Integration")
f.StringVar(&b.Configuration.S3.Endpoint, arg("s3.endpoint"), "", "Endpoint of S3 API implementation")
f.StringVar(&b.Configuration.S3.CACrtFile, arg("s3.ca-crt"), "", "Path to file containing CA certificate to validate endpoint connection")
f.StringVar(&b.Configuration.S3.CAKeyFile, arg("s3.ca-key"), "", "Path to file containing keyfile to validate endpoint connection")
f.BoolVar(&b.Configuration.S3.AllowInsecure, arg("s3.allow-insecure"), false, "If set to true, the Endpoint certificates won't be checked")
f.BoolVar(&b.Configuration.S3.DisableSSL, arg("s3.disable-ssl"), false, "If set to true, the SSL won't be used when connecting to Endpoint")
f.StringVar(&b.Configuration.S3.Region, arg("s3.region"), "", "Region")
f.StringVar(&b.Configuration.S3.BucketName, arg("s3.bucket"), "", "Bucket name")
f.StringVar(&b.Configuration.S3.AccessKeyFile, arg("s3.access-key"), "", "Path to file containing S3 AccessKey")
f.StringVar(&b.Configuration.S3.SecretKeyFile, arg("s3.secret-key"), "", "Path to file containing S3 SecretKey")
return nil
}
func (b *storageV1) Handler(ctx context.Context) (svc.Handler, error) {
return storage.NewService(ctx, b.Configuration)
}

View file

@ -1,98 +0,0 @@
//
// DISCLAIMER
//
// Copyright 2023-2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package cmd
import (
"os"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"github.com/arangodb/kube-arangodb/pkg/ml/storage"
"github.com/arangodb/kube-arangodb/pkg/util/shutdown"
"github.com/arangodb/kube-arangodb/pkg/util/svc"
)
var (
cmdMLStorage = &cobra.Command{
Use: "storage",
Run: func(cmd *cobra.Command, args []string) {
},
Hidden: true,
}
cmdMLStorageS3 = &cobra.Command{
Use: "s3",
Short: "Run a GRPC service implementing the arangodb.operator.ml.storage.v1 API. Enterprise Edition only",
Run: cmdMLStorageS3Run,
}
cmdMLStorageS3Options struct {
storage.ServiceConfig
}
cmdMLStorageControllerOptions struct {
Configuration svc.Configuration
}
)
func init() {
cmdML.AddCommand(cmdMLStorage)
cmdMLStorage.AddCommand(cmdMLStorageS3)
f := cmdMLStorageS3.PersistentFlags()
f.StringVar(&cmdMLStorageControllerOptions.Configuration.Address, "controller.address", "", "Address the GRPC controller service will listen on (IP:port)")
f.StringVar(&cmdMLStorageS3Options.Configuration.Address, "server.address", "", "Address the GRPC service will listen on (IP:port)")
f.StringVar(&cmdMLStorageS3Options.S3.Endpoint, "s3.endpoint", "", "Endpoint of S3 API implementation")
f.StringVar(&cmdMLStorageS3Options.S3.CACrtFile, "s3.ca-crt", "", "Path to file containing CA certificate to validate endpoint connection")
f.StringVar(&cmdMLStorageS3Options.S3.CAKeyFile, "s3.ca-key", "", "Path to file containing keyfile to validate endpoint connection")
f.BoolVar(&cmdMLStorageS3Options.S3.AllowInsecure, "s3.allow-insecure", false, "If set to true, the Endpoint certificates won't be checked")
f.BoolVar(&cmdMLStorageS3Options.S3.DisableSSL, "s3.disable-ssl", false, "If set to true, the SSL won't be used when connecting to Endpoint")
f.StringVar(&cmdMLStorageS3Options.S3.Region, "s3.region", "", "Region")
f.StringVar(&cmdMLStorageS3Options.S3.BucketName, "s3.bucket", "", "Bucket name")
f.StringVar(&cmdMLStorageS3Options.S3.AccessKeyFile, "s3.access-key", "", "Path to file containing S3 AccessKey")
f.StringVar(&cmdMLStorageS3Options.S3.SecretKeyFile, "s3.secret-key", "", "Path to file containing S3 SecretKey")
}
func cmdMLStorageS3Run(cmd *cobra.Command, _ []string) {
if err := cmdMLStorageS3RunE(cmd); err != nil {
log.Error().Err(err).Msgf("Fatal")
os.Exit(1)
}
}
func cmdMLStorageS3RunE(_ *cobra.Command) error {
health := svc.NewHealthService(cmdMLStorageControllerOptions.Configuration, svc.Readiness, shutdown.NewGlobalShutdownServer())
health.Start(shutdown.Context())
storageService, err := storage.NewService(shutdown.Context(), storage.StorageTypeS3Proxy, cmdMLStorageS3Options.ServiceConfig)
if err != nil {
return err
}
svc := svc.NewService(cmdMLStorageS3Options.Configuration, storageService)
svcRun := svc.StartWithHealth(shutdown.Context(), health)
return svcRun.Wait()
}

View file

@ -0,0 +1,156 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.21.1
// source: integrations/shared/v1/definition/empty.proto
package definition
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type Empty struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *Empty) Reset() {
*x = Empty{}
if protoimpl.UnsafeEnabled {
mi := &file_integrations_shared_v1_definition_empty_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Empty) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Empty) ProtoMessage() {}
func (x *Empty) ProtoReflect() protoreflect.Message {
mi := &file_integrations_shared_v1_definition_empty_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Empty.ProtoReflect.Descriptor instead.
func (*Empty) Descriptor() ([]byte, []int) {
return file_integrations_shared_v1_definition_empty_proto_rawDescGZIP(), []int{0}
}
var File_integrations_shared_v1_definition_empty_proto protoreflect.FileDescriptor
var file_integrations_shared_v1_definition_empty_proto_rawDesc = []byte{
0x0a, 0x2d, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73,
0x68, 0x61, 0x72, 0x65, 0x64, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74,
0x69, 0x6f, 0x6e, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
0x06, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x22, 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79,
0x42, 0x45, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61,
0x72, 0x61, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x6b, 0x75, 0x62, 0x65, 0x2d, 0x61, 0x72, 0x61,
0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x73, 0x2f, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x66,
0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_integrations_shared_v1_definition_empty_proto_rawDescOnce sync.Once
file_integrations_shared_v1_definition_empty_proto_rawDescData = file_integrations_shared_v1_definition_empty_proto_rawDesc
)
func file_integrations_shared_v1_definition_empty_proto_rawDescGZIP() []byte {
file_integrations_shared_v1_definition_empty_proto_rawDescOnce.Do(func() {
file_integrations_shared_v1_definition_empty_proto_rawDescData = protoimpl.X.CompressGZIP(file_integrations_shared_v1_definition_empty_proto_rawDescData)
})
return file_integrations_shared_v1_definition_empty_proto_rawDescData
}
var file_integrations_shared_v1_definition_empty_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_integrations_shared_v1_definition_empty_proto_goTypes = []interface{}{
(*Empty)(nil), // 0: shared.Empty
}
var file_integrations_shared_v1_definition_empty_proto_depIdxs = []int32{
0, // [0:0] is the sub-list for method output_type
0, // [0:0] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_integrations_shared_v1_definition_empty_proto_init() }
func file_integrations_shared_v1_definition_empty_proto_init() {
if File_integrations_shared_v1_definition_empty_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_integrations_shared_v1_definition_empty_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Empty); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_integrations_shared_v1_definition_empty_proto_rawDesc,
NumEnums: 0,
NumMessages: 1,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_integrations_shared_v1_definition_empty_proto_goTypes,
DependencyIndexes: file_integrations_shared_v1_definition_empty_proto_depIdxs,
MessageInfos: file_integrations_shared_v1_definition_empty_proto_msgTypes,
}.Build()
File_integrations_shared_v1_definition_empty_proto = out.File
file_integrations_shared_v1_definition_empty_proto_rawDesc = nil
file_integrations_shared_v1_definition_empty_proto_goTypes = nil
file_integrations_shared_v1_definition_empty_proto_depIdxs = nil
}

View file

@ -0,0 +1,27 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
syntax = "proto3";
option go_package = "github.com/arangodb/kube-arangodb/integrations/shared/v1/definition";
package shared;
message Empty {}

View file

@ -0,0 +1,25 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package v1
const (
Name = "shutdown.v1"
)

View file

@ -0,0 +1,99 @@
//
// DISCLAIMER
//
// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.21.1
// source: integrations/shutdown/v1/definition/shutdown.proto
package definition
import (
definition "github.com/arangodb/kube-arangodb/integrations/shared/v1/definition"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
var File_integrations_shutdown_v1_definition_shutdown_proto protoreflect.FileDescriptor
var file_integrations_shutdown_v1_definition_shutdown_proto_rawDesc = []byte{
0x0a, 0x32, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73,
0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e,
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x73, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x73, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x1a, 0x2d,
0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x68, 0x61,
0x72, 0x65, 0x64, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f,
0x6e, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x3c, 0x0a,
0x08, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x30, 0x0a, 0x0e, 0x53, 0x68, 0x75,
0x74, 0x64, 0x6f, 0x77, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x0d, 0x2e, 0x73, 0x68,
0x61, 0x72, 0x65, 0x64, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0d, 0x2e, 0x73, 0x68, 0x61,
0x72, 0x65, 0x64, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x47, 0x5a, 0x45, 0x67,
0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x6f,
0x64, 0x62, 0x2f, 0x6b, 0x75, 0x62, 0x65, 0x2d, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x6f, 0x64, 0x62,
0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x68,
0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69,
0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var file_integrations_shutdown_v1_definition_shutdown_proto_goTypes = []interface{}{
(*definition.Empty)(nil), // 0: shared.Empty
}
var file_integrations_shutdown_v1_definition_shutdown_proto_depIdxs = []int32{
0, // 0: shutdown.Shutdown.ShutdownServer:input_type -> shared.Empty
0, // 1: shutdown.Shutdown.ShutdownServer:output_type -> shared.Empty
1, // [1:2] is the sub-list for method output_type
0, // [0:1] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_integrations_shutdown_v1_definition_shutdown_proto_init() }
func file_integrations_shutdown_v1_definition_shutdown_proto_init() {
if File_integrations_shutdown_v1_definition_shutdown_proto != nil {
return
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_integrations_shutdown_v1_definition_shutdown_proto_rawDesc,
NumEnums: 0,
NumMessages: 0,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_integrations_shutdown_v1_definition_shutdown_proto_goTypes,
DependencyIndexes: file_integrations_shutdown_v1_definition_shutdown_proto_depIdxs,
}.Build()
File_integrations_shutdown_v1_definition_shutdown_proto = out.File
file_integrations_shutdown_v1_definition_shutdown_proto_rawDesc = nil
file_integrations_shutdown_v1_definition_shutdown_proto_goTypes = nil
file_integrations_shutdown_v1_definition_shutdown_proto_depIdxs = nil
}

View file

@ -20,12 +20,12 @@
syntax = "proto3";
option go_package = "github.com/arangodb/kube-arangodb/pkg/api/shutdown";
option go_package = "github.com/arangodb/kube-arangodb/integrations/shutdown/v1/definition";
package server;
package shutdown;
import "pkg/api/server/operator.proto";
import "integrations/shared/v1/definition/empty.proto";
service Shutdown {
rpc ShutdownServer (Empty) returns (Empty) {}
rpc ShutdownServer (shared.Empty) returns (shared.Empty) {}
}

View file

@ -2,13 +2,13 @@
// versions:
// - protoc-gen-go-grpc v1.2.0
// - protoc v3.21.1
// source: pkg/api/shutdown/v1/operator.proto
// source: integrations/shutdown/v1/definition/shutdown.proto
package shutdown
package definition
import (
context "context"
server "github.com/arangodb/kube-arangodb/pkg/api/server"
definition "github.com/arangodb/kube-arangodb/integrations/shared/v1/definition"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
@ -23,7 +23,7 @@ const _ = grpc.SupportPackageIsVersion7
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type ShutdownClient interface {
ShutdownServer(ctx context.Context, in *server.Empty, opts ...grpc.CallOption) (*server.Empty, error)
ShutdownServer(ctx context.Context, in *definition.Empty, opts ...grpc.CallOption) (*definition.Empty, error)
}
type shutdownClient struct {
@ -34,9 +34,9 @@ func NewShutdownClient(cc grpc.ClientConnInterface) ShutdownClient {
return &shutdownClient{cc}
}
func (c *shutdownClient) ShutdownServer(ctx context.Context, in *server.Empty, opts ...grpc.CallOption) (*server.Empty, error) {
out := new(server.Empty)
err := c.cc.Invoke(ctx, "/server.Shutdown/ShutdownServer", in, out, opts...)
func (c *shutdownClient) ShutdownServer(ctx context.Context, in *definition.Empty, opts ...grpc.CallOption) (*definition.Empty, error) {
out := new(definition.Empty)
err := c.cc.Invoke(ctx, "/shutdown.Shutdown/ShutdownServer", in, out, opts...)
if err != nil {
return nil, err
}
@ -47,7 +47,7 @@ func (c *shutdownClient) ShutdownServer(ctx context.Context, in *server.Empty, o
// All implementations must embed UnimplementedShutdownServer
// for forward compatibility
type ShutdownServer interface {
ShutdownServer(context.Context, *server.Empty) (*server.Empty, error)
ShutdownServer(context.Context, *definition.Empty) (*definition.Empty, error)
mustEmbedUnimplementedShutdownServer()
}
@ -55,7 +55,7 @@ type ShutdownServer interface {
type UnimplementedShutdownServer struct {
}
func (UnimplementedShutdownServer) ShutdownServer(context.Context, *server.Empty) (*server.Empty, error) {
func (UnimplementedShutdownServer) ShutdownServer(context.Context, *definition.Empty) (*definition.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method ShutdownServer not implemented")
}
func (UnimplementedShutdownServer) mustEmbedUnimplementedShutdownServer() {}
@ -72,7 +72,7 @@ func RegisterShutdownServer(s grpc.ServiceRegistrar, srv ShutdownServer) {
}
func _Shutdown_ShutdownServer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(server.Empty)
in := new(definition.Empty)
if err := dec(in); err != nil {
return nil, err
}
@ -81,10 +81,10 @@ func _Shutdown_ShutdownServer_Handler(srv interface{}, ctx context.Context, dec
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/server.Shutdown/ShutdownServer",
FullMethod: "/shutdown.Shutdown/ShutdownServer",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ShutdownServer).ShutdownServer(ctx, req.(*server.Empty))
return srv.(ShutdownServer).ShutdownServer(ctx, req.(*definition.Empty))
}
return interceptor(ctx, in, info, handler)
}
@ -93,7 +93,7 @@ func _Shutdown_ShutdownServer_Handler(srv interface{}, ctx context.Context, dec
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var Shutdown_ServiceDesc = grpc.ServiceDesc{
ServiceName: "server.Shutdown",
ServiceName: "shutdown.Shutdown",
HandlerType: (*ShutdownServer)(nil),
Methods: []grpc.MethodDesc{
{
@ -102,5 +102,5 @@ var Shutdown_ServiceDesc = grpc.ServiceDesc{
},
},
Streams: []grpc.StreamDesc{},
Metadata: "pkg/api/shutdown/v1/operator.proto",
Metadata: "integrations/shutdown/v1/definition/shutdown.proto",
}

View file

@ -18,7 +18,7 @@
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package shutdown
package v1
import (
"context"
@ -26,30 +26,26 @@ import (
"google.golang.org/grpc"
"github.com/arangodb/kube-arangodb/pkg/api/server"
pbShutdown "github.com/arangodb/kube-arangodb/pkg/api/shutdown/v1"
pbSharedV1 "github.com/arangodb/kube-arangodb/integrations/shared/v1/definition"
pbShutdownV1 "github.com/arangodb/kube-arangodb/integrations/shutdown/v1/definition"
"github.com/arangodb/kube-arangodb/pkg/util/svc"
)
func NewGlobalShutdownServer() svc.Handler {
return NewShutdownServer(stop)
}
func NewShutdownServer(closer context.CancelFunc) svc.Handler {
func New(closer context.CancelFunc) svc.Handler {
return &impl{closer: closer}
}
var _ pbShutdown.ShutdownServer = &impl{}
var _ pbShutdownV1.ShutdownServer = &impl{}
var _ svc.Handler = &impl{}
type impl struct {
pbShutdown.UnimplementedShutdownServer
pbShutdownV1.UnimplementedShutdownServer
closer context.CancelFunc
}
func (i *impl) Name() string {
return "shutdown"
return Name
}
func (i *impl) Health() svc.HealthState {
@ -57,15 +53,15 @@ func (i *impl) Health() svc.HealthState {
}
func (i *impl) Register(registrar *grpc.Server) {
pbShutdown.RegisterShutdownServer(registrar, i)
pbShutdownV1.RegisterShutdownServer(registrar, i)
}
func (i *impl) ShutdownServer(ctx context.Context, empty *server.Empty) (*server.Empty, error) {
func (i *impl) ShutdownServer(ctx context.Context, empty *pbSharedV1.Empty) (*pbSharedV1.Empty, error) {
go func() {
defer i.closer()
time.Sleep(50 * time.Millisecond)
}()
return &server.Empty{}, nil
return &pbSharedV1.Empty{}, nil
}

View file

@ -18,7 +18,7 @@
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package shutdown
package v1
import (
"context"
@ -27,8 +27,8 @@ import (
"github.com/stretchr/testify/require"
"github.com/arangodb/kube-arangodb/pkg/api/server"
pbShutdown "github.com/arangodb/kube-arangodb/pkg/api/shutdown/v1"
pbSharedV1 "github.com/arangodb/kube-arangodb/integrations/shared/v1/definition"
pbShutdownV1 "github.com/arangodb/kube-arangodb/integrations/shutdown/v1/definition"
"github.com/arangodb/kube-arangodb/pkg/util/svc"
"github.com/arangodb/kube-arangodb/pkg/util/tests/tgrpc"
)
@ -39,15 +39,15 @@ func Test_ShutdownGRPC(t *testing.T) {
local := svc.NewService(svc.Configuration{
Address: "127.0.0.1:0",
}, NewShutdownServer(c))
}, New(c))
start := local.Start(ctx)
require.False(t, isContextDone(ctx))
client := tgrpc.NewGRPCClient(t, ctx, pbShutdown.NewShutdownClient, start.Address())
client := tgrpc.NewGRPCClient(t, ctx, pbShutdownV1.NewShutdownClient, start.Address())
_, err := client.ShutdownServer(ctx, &server.Empty{})
_, err := client.ShutdownServer(ctx, &pbSharedV1.Empty{})
require.NoError(t, err)
time.Sleep(time.Second)

View file

@ -1,96 +0,0 @@
//
// DISCLAIMER
//
// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.21.1
// source: pkg/api/shutdown/v1/operator.proto
package shutdown
import (
server "github.com/arangodb/kube-arangodb/pkg/api/server"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
var File_pkg_api_shutdown_v1_operator_proto protoreflect.FileDescriptor
var file_pkg_api_shutdown_v1_operator_proto_rawDesc = []byte{
0x0a, 0x22, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x68, 0x75, 0x74, 0x64, 0x6f,
0x77, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x1a, 0x1d, 0x70, 0x6b,
0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x6f, 0x70, 0x65,
0x72, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x3c, 0x0a, 0x08, 0x53,
0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x30, 0x0a, 0x0e, 0x53, 0x68, 0x75, 0x74, 0x64,
0x6f, 0x77, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76,
0x65, 0x72, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65,
0x72, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74,
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x6f, 0x64, 0x62,
0x2f, 0x6b, 0x75, 0x62, 0x65, 0x2d, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x70,
0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x62,
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var file_pkg_api_shutdown_v1_operator_proto_goTypes = []interface{}{
(*server.Empty)(nil), // 0: server.Empty
}
var file_pkg_api_shutdown_v1_operator_proto_depIdxs = []int32{
0, // 0: server.Shutdown.ShutdownServer:input_type -> server.Empty
0, // 1: server.Shutdown.ShutdownServer:output_type -> server.Empty
1, // [1:2] is the sub-list for method output_type
0, // [0:1] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_pkg_api_shutdown_v1_operator_proto_init() }
func file_pkg_api_shutdown_v1_operator_proto_init() {
if File_pkg_api_shutdown_v1_operator_proto != nil {
return
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_pkg_api_shutdown_v1_operator_proto_rawDesc,
NumEnums: 0,
NumMessages: 0,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_pkg_api_shutdown_v1_operator_proto_goTypes,
DependencyIndexes: file_pkg_api_shutdown_v1_operator_proto_depIdxs,
}.Build()
File_pkg_api_shutdown_v1_operator_proto = out.File
file_pkg_api_shutdown_v1_operator_proto_rawDesc = nil
file_pkg_api_shutdown_v1_operator_proto_goTypes = nil
file_pkg_api_shutdown_v1_operator_proto_depIdxs = nil
}

View file

@ -1,7 +1,7 @@
//
// DISCLAIMER
//
// Copyright 2023-2024 ArangoDB GmbH, Cologne, Germany
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -22,16 +22,16 @@ package storage
import (
"github.com/arangodb/kube-arangodb/pkg/ml/storage/s3"
"github.com/arangodb/kube-arangodb/pkg/util/svc"
)
type StorageType string
type Type string
const (
StorageTypeS3Proxy = StorageType("s3")
S3 = Type("s3")
)
type ServiceConfig struct {
Configuration svc.Configuration
S3 s3.Config
type Configuration struct {
Type Type
S3 s3.Configuration
}

View file

@ -1,5 +1,7 @@
//
// Copyright 2023-2024 ArangoDB GmbH, Cologne, Germany
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -20,7 +22,7 @@ package s3
import "github.com/arangodb/kube-arangodb/pkg/util/errors"
type Config struct {
type Configuration struct {
Endpoint string
AllowInsecure bool
CACrtFile string
@ -32,7 +34,7 @@ type Config struct {
SecretKeyFile string // path to file containing S3 SecretKey
}
func (c Config) Validate() error {
func (c Configuration) Validate() error {
if c.AccessKeyFile == "" {
return errors.Errorf("AccessKeyFile is not defined")
}

View file

@ -29,6 +29,6 @@ import (
"github.com/arangodb/kube-arangodb/pkg/util/svc"
)
func NewService(_ context.Context, _ StorageType, _ ServiceConfig) (svc.Handler, error) {
func NewService(_ context.Context, _ Configuration) (svc.Handler, error) {
return nil, errors.New("this service is available only in enterprise edition of operator")
}

View file

@ -1,7 +1,7 @@
//
// DISCLAIMER
//
// Copyright 2016-2023 ArangoDB GmbH, Cologne, Germany
// Copyright 2016-2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -25,6 +25,9 @@ import (
"os"
"os/signal"
"syscall"
pbImplShutdownV1 "github.com/arangodb/kube-arangodb/integrations/shutdown/v1"
"github.com/arangodb/kube-arangodb/pkg/util/svc"
)
func init() {
@ -40,6 +43,10 @@ func init() {
}()
}
func NewGlobalShutdownServer() svc.Handler {
return pbImplShutdownV1.New(stop)
}
var (
ctx context.Context
stop context.CancelFunc

27
pkg/util/svc/shutdown.go Normal file
View file

@ -0,0 +1,27 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package svc
import "context"
type Shutdown interface {
Shutdown(cancelFunc context.CancelFunc)
}