Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce amount of API calls the CSI driver performs #112

Merged
merged 6 commits into from May 7, 2020
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGES.md
@@ -1,12 +1,14 @@
# Changes

## master

- Update `csi-attacher` sidecar to v2.2.0
- Update `csi-provisioner` sidecar to v1.6.0
- Update `csi-node-driver-registrar` sidecar to v1.3.0
- Add livenessProbe support
- Update Go to 1.14
- Reduce the amount of API calls from CSI driver
- Add option to configure the Action polling interval via `HCLOUD_POLLING_INTERVAL_SECONDS`
- Add option to enable the debug mode via `HCLOUD_DEBUG`

## v1.2.3

Expand Down
3 changes: 2 additions & 1 deletion api/volume.go
Expand Up @@ -2,6 +2,7 @@ package api

import (
"context"
"time"

"github.com/go-kit/kit/log"
"github.com/go-kit/kit/log/level"
Expand Down Expand Up @@ -210,7 +211,7 @@ func (s *VolumeService) Attach(ctx context.Context, volume *csi.Volume, server *
}
return err
}

time.Sleep(3 * time.Second) // We know that the Attach action will take some time, so we wait 3 seconds before starting polling the action status. Within these 3 seconds the volume attach action may be already finished.
_, errCh := s.client.Action.WatchProgress(ctx, action)
if err := <-errCh; err != nil {
level.Info(s.logger).Log(
Expand Down
32 changes: 28 additions & 4 deletions cmd/driver/main.go
Expand Up @@ -8,6 +8,7 @@ import (
"os"
"strconv"
"strings"
"time"

proto "github.com/container-storage-interface/spec/lib/go/csi"
"github.com/go-kit/kit/log"
Expand Down Expand Up @@ -67,13 +68,36 @@ func main() {
os.Exit(2)
}

hcloudServerID := getServerID()

hcloudClient := hcloud.NewClient(
opts := []hcloud.ClientOption{
hcloud.WithToken(apiToken),
hcloud.WithApplication("csi-driver", driver.PluginVersion),
)
}

enableDebug := os.Getenv("HCLOUD_DEBUG")
if enableDebug != "" {
opts = append(opts, hcloud.WithDebugWriter(os.Stdout))
}

pollingInterval := 1
if customPollingInterval := os.Getenv("HCLOUD_POLLING_INTERVAL_SECONDS"); customPollingInterval != "" {
tmp, err := strconv.Atoi(customPollingInterval)
if err != nil || tmp < 1 {
level.Error(logger).Log(
"msg", "entered polling interval configuration is not a integer that is higher than 1",
)
os.Exit(2)
}
LKaemmerling marked this conversation as resolved.
Show resolved Hide resolved
level.Info(logger).Log(
"msg", "got custom configuration for polling interval", customPollingInterval,
LKaemmerling marked this conversation as resolved.
Show resolved Hide resolved
)

pollingInterval = tmp
}
opts = append(opts, hcloud.WithPollInterval(time.Duration(pollingInterval)*time.Second))

hcloudClient := hcloud.NewClient(opts...)

hcloudServerID := getServerID()
level.Debug(logger).Log("msg", "fetching server")
server, _, err := hcloudClient.Server.GetByID(context.Background(), hcloudServerID)
if err != nil {
Expand Down
21 changes: 3 additions & 18 deletions driver/node.go
Expand Up @@ -202,30 +202,15 @@ func (s *NodeService) NodeGetVolumeStats(ctx context.Context, req *proto.NodeGet
return nil, status.Error(codes.InvalidArgument, "missing volume path")
}

volumeID, err := parseVolumeID(req.VolumeId)
if err != nil {
return nil, status.Error(codes.NotFound, "volume not found")
}

volume, err := s.volumeService.GetByID(ctx, volumeID)
if err != nil {
switch err {
case volumes.ErrVolumeNotFound:
return nil, status.Error(codes.NotFound, "volume not found")
default:
return nil, status.Error(codes.Internal, fmt.Sprintf("failed to get volume: %s", err))
}
}

volumeExists, err := s.volumeMountService.PathExists(req.VolumePath)
if err != nil {
return nil, status.Error(codes.Internal, fmt.Sprintf("failed to check for volume existence: %s", err))
}
if !volumeExists {
return nil, status.Error(codes.NotFound, fmt.Sprintf("volume %s is not available on this node %v", volume.LinuxDevice, s.server.ID))
return nil, status.Error(codes.NotFound, fmt.Sprintf("volume %s is not available on this node %v", req.VolumePath, s.server.ID))
}

availableBytes, usedBytes, err := s.volumeStatsService.ByteFilesystemStats(req.VolumePath)
totalBytes, availableBytes, usedBytes, err := s.volumeStatsService.ByteFilesystemStats(req.VolumePath)
if err != nil {
return nil, status.Error(codes.Internal, fmt.Sprintf("failed to get volume byte stats: %s", err))
}
Expand All @@ -240,7 +225,7 @@ func (s *NodeService) NodeGetVolumeStats(ctx context.Context, req *proto.NodeGet
{
Unit: proto.VolumeUsage_BYTES,
Available: availableBytes,
Total: volume.SizeBytes(),
Total: totalBytes,
Used: usedBytes,
},
{
Expand Down
4 changes: 2 additions & 2 deletions driver/sanity_test.go
Expand Up @@ -216,8 +216,8 @@ func (s *sanityResizeService) Resize(volume *csi.Volume, volumePath string) erro

type sanityStatsService struct{}

func (s *sanityStatsService) ByteFilesystemStats(volumePath string) (availableBytes int64, usedBytes int64, err error) {
return 1, 1, nil
func (s *sanityStatsService) ByteFilesystemStats(volumePath string) (totalBytes int64, availableBytes int64, usedBytes int64, err error) {
return 1, 1, 1, nil
}
func (s *sanityStatsService) INodeFilesystemStats(volumePath string) (total int64, used int64, free int64, err error) {
return 1, 1, 1, nil
Expand Down
4 changes: 2 additions & 2 deletions mock/volume.go
Expand Up @@ -121,11 +121,11 @@ func (s *VolumeResizeService) Resize(volume *csi.Volume, volumePath string) erro
}

type VolumeStatsService struct {
ByteFilesystemStatsFunc func(volumePath string) (availableBytes int64, usedBytes int64, err error)
ByteFilesystemStatsFunc func(volumePath string) (totalBytes int64, availableBytes int64, usedBytes int64, err error)
INodeFilesystemStatsFunc func(volumePath string) (total int64, used int64, free int64, err error)
}

func (s *VolumeStatsService) ByteFilesystemStats(volumePath string) (availableBytes int64, usedBytes int64, err error) {
func (s *VolumeStatsService) ByteFilesystemStats(volumePath string) (totalBytes int64, availableBytes int64, usedBytes int64, err error) {
if s.ByteFilesystemStatsFunc == nil {
panic("not implemented")
}
Expand Down
5 changes: 3 additions & 2 deletions volumes/stats.go
Expand Up @@ -7,7 +7,7 @@ import (

// StatsService get statistics about mounted volumes.
type StatsService interface {
ByteFilesystemStats(volumePath string) (availableBytes int64, usedBytes int64, err error)
ByteFilesystemStats(volumePath string) (totalBytes int64, availableBytes int64, usedBytes int64, err error)
INodeFilesystemStats(volumePath string) (total int64, used int64, free int64, err error)
}

Expand All @@ -22,14 +22,15 @@ func NewLinuxStatsService(logger log.Logger) *LinuxStatsService {
}
}

func (l *LinuxStatsService) ByteFilesystemStats(volumePath string) (availableBytes int64, usedBytes int64, err error) {
func (l *LinuxStatsService) ByteFilesystemStats(volumePath string) (totalBytes int64, availableBytes int64, usedBytes int64, err error) {
statfs := &unix.Statfs_t{}
err = unix.Statfs(volumePath, statfs)
if err != nil {
return
}
availableBytes = int64(statfs.Bavail) * int64(statfs.Bsize)
usedBytes = (int64(statfs.Blocks) - int64(statfs.Bfree)) * int64(statfs.Bsize)
totalBytes = int64(statfs.Blocks) * int64(statfs.Bsize)
return
}

Expand Down