Skip to content

Commit

Permalink
Reduce amount of API calls the CSI driver performs (#112)
Browse files Browse the repository at this point in the history
  • Loading branch information
LKaemmerling committed May 7, 2020
1 parent e140055 commit d429f6f
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 30 deletions.
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
33 changes: 29 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,37 @@ 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)
}
level.Info(logger).Log(
"msg", "got custom configuration for polling interval",
"interval", customPollingInterval,
)

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

0 comments on commit d429f6f

Please sign in to comment.