Skip to content
Merged
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
1,028 changes: 1,028 additions & 0 deletions client/api/disk/v1beta2/api.pb.go

Large diffs are not rendered by default.

109 changes: 109 additions & 0 deletions client/api/disk/v1beta2/api.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
syntax = "proto3";

package v1beta2;

option go_package = "github.com/kubernetes-csi/csi-proxy/client/api/disk/v1beta2";

service Disk {
// ListDiskLocations returns locations <Adapter, Bus, Target, LUN ID> of all
// disk devices enumerated by the host
rpc ListDiskLocations(ListDiskLocationsRequest) returns (ListDiskLocationsResponse) {}

// PartitionDisk initializes and partitions a disk device (if the disk has not
// been partitioned already) and returns the resulting volume device ID
rpc PartitionDisk(PartitionDiskRequest) returns (PartitionDiskResponse) {}

// Rescan refreshes the host's storage cache
rpc Rescan(RescanRequest) returns (RescanResponse) {}

// ListDiskIDs returns a map of DiskID objects where the key is the disk number
rpc ListDiskIDs(ListDiskIDsRequest) returns (ListDiskIDsResponse) {}

// DiskStats returns the stats for the disk
rpc DiskStats(DiskStatsRequest) returns (DiskStatsResponse) {}

// SetAttachState sets the offline/online state of a disk
rpc SetAttachState(SetAttachStateRequest) returns (SetAttachStateResponse) {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you also add a GetAttachState please?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added, PTAL


// GetAttachState gets the offline/online state of a disk
rpc GetAttachState(GetAttachStateRequest) returns (GetAttachStateResponse) {}
}

message ListDiskLocationsRequest {
// Intentionally empty
}

message DiskLocation {
string Adapter = 1;
string Bus = 2;
string Target = 3;
string LUNID = 4;
}

message ListDiskLocationsResponse {
// Map of disk device IDs and <adapter, bus, target, lun ID> associated with each disk device
map <string, DiskLocation> disk_locations = 1;
}

message PartitionDiskRequest {
// Disk device ID of the disk to partition
string diskID = 1;
}

message PartitionDiskResponse {
// Intentionally empty
}

message RescanRequest {
// Intentionally empty
}

message RescanResponse {
// Intentionally empty
}

message ListDiskIDsRequest {
// Intentionally empty
}

message DiskIDs {
// Map of Disk ID types and Disk ID values
map <string, string> identifiers = 1;
}

message ListDiskIDsResponse {
// Map of disk device numbers and IDs <page83> associated with each disk device
map <string, DiskIDs> diskIDs = 1;
}

message DiskStatsRequest {
// Disk device ID of the disk to get the size from
string diskID = 1;
}

message DiskStatsResponse {
//Total size of the volume
int64 diskSize = 1;
}

message SetAttachStateRequest {
// Disk device ID (number) of the disk which state will change
string diskID = 1;

// Online state to set for the disk. true for online, false for offline
bool isOnline = 2;
}

message SetAttachStateResponse {
}

message GetAttachStateRequest {
// Disk device ID (number) of the disk
string diskID = 1;
}

message GetAttachStateResponse {
// Online state of the disk. true for online, false for offline
bool isOnline = 1;
}

80 changes: 80 additions & 0 deletions client/groups/disk/v1beta2/client_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

71 changes: 66 additions & 5 deletions integrationtests/disk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,32 @@ package integrationtests

import (
"context"
"fmt"
"math/rand"
"strconv"
"strings"
"testing"
"time"

"github.com/kubernetes-csi/csi-proxy/client/api/disk/v1beta1"
v1beta1client "github.com/kubernetes-csi/csi-proxy/client/groups/disk/v1beta1"
"github.com/kubernetes-csi/csi-proxy/client/api/disk/v1beta2"
v1beta2client "github.com/kubernetes-csi/csi-proxy/client/groups/disk/v1beta2"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

// This test is meant to run on GCE where the page83 ID of the first disk contains
// the host name
// Skip on Github Actions as it is expected to fail
func TestDiskAPIGroupV1Beta1(t *testing.T) {
func TestDiskAPIGroup(t *testing.T) {
t.Run("ListDiskIDs", func(t *testing.T) {
skipTestOnCondition(t, isRunningOnGhActions())
client, err := v1beta1client.NewClient()
client, err := v1beta2client.NewClient()
require.Nil(t, err)
defer client.Close()

diskNumber := 0
id := "page83"
listRequest := &v1beta1.ListDiskIDsRequest{}
listRequest := &v1beta2.ListDiskIDsRequest{}
diskIDsResponse, err := client.ListDiskIDs(context.TODO(), listRequest)
require.Nil(t, err)

Expand Down Expand Up @@ -53,4 +57,61 @@ func TestDiskAPIGroupV1Beta1(t *testing.T) {
}
}
})

t.Run("Get/SetAttachState", func(t *testing.T) {
skipTestOnCondition(t, isRunningOnGhActions())
client, err := v1beta2client.NewClient()
require.NoError(t, err)

defer client.Close()

s1 := rand.NewSource(time.Now().UTC().UnixNano())
r1 := rand.New(s1)

testPluginPath := fmt.Sprintf("C:\\var\\lib\\kubelet\\plugins\\testplugin-%d.csi.io\\", r1.Intn(100))
mountPath := fmt.Sprintf("%smount-%d", testPluginPath, r1.Intn(100))
vhdxPath := fmt.Sprintf("%sdisk-%d.vhdx", testPluginPath, r1.Intn(100))

defer diskCleanup(t, vhdxPath, mountPath, testPluginPath)
diskNum := diskInit(t, vhdxPath, mountPath, testPluginPath)

out, err := runPowershellCmd(fmt.Sprintf("Get-Disk -Number %s | Set-Disk -IsOffline $true", diskNum))
require.NoError(t, err, "failed setting disk offline, out=%v", out)

getReq := &v1beta2.GetAttachStateRequest{DiskID: diskNum}
getResp, err := client.GetAttachState(context.TODO(), getReq)

if assert.NoError(t, err) {
assert.False(t, getResp.IsOnline, "Expected disk to be offline")
}

setReq := &v1beta2.SetAttachStateRequest{DiskID: diskNum, IsOnline: true}
_, err = client.SetAttachState(context.TODO(), setReq)
assert.NoError(t, err)

out, err = runPowershellCmd(fmt.Sprintf("Get-Disk -Number %s | Select-Object -ExpandProperty IsOffline", diskNum))
assert.NoError(t, err)

result, err := strconv.ParseBool(strings.TrimSpace(out))
assert.NoError(t, err)
assert.False(t, result, "Expected disk to be online")

getReq = &v1beta2.GetAttachStateRequest{DiskID: diskNum}
getResp, err = client.GetAttachState(context.TODO(), getReq)

if assert.NoError(t, err) {
assert.True(t, getResp.IsOnline, "Expected disk is online")
}

setReq = &v1beta2.SetAttachStateRequest{DiskID: diskNum, IsOnline: false}
_, err = client.SetAttachState(context.TODO(), setReq)
assert.NoError(t, err)

out, err = runPowershellCmd(fmt.Sprintf("Get-Disk -Number %s | Select-Object -ExpandProperty IsOffline", diskNum))
assert.NoError(t, err)

result, err = strconv.ParseBool(strings.TrimSpace(out))
assert.NoError(t, err)
assert.True(t, result, "Expected disk to be offline")
})
}
26 changes: 26 additions & 0 deletions internal/os/disk/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,3 +318,29 @@ func (imp APIImplementor) DiskStats(diskID string) (int64, error) {

return diskSize, nil
}

func (imp APIImplementor) SetAttachState(diskID string, isOnline bool) error {
cmd := fmt.Sprintf("(Get-Disk -Number %s) | Set-Disk -IsOffline $%t", diskID, !isOnline)
out, err := exec.Command("powershell", "/c", cmd).CombinedOutput()
if err != nil {
return fmt.Errorf("error setting disk attach state. cmd: %s, output: %s, error: %v", cmd, string(out), err)
}

return nil
}

func (imp APIImplementor) GetAttachState(diskID string) (bool, error) {
cmd := fmt.Sprintf("(Get-Disk -Number %s) | Select-Object -ExpandProperty IsOffline", diskID)
out, err := exec.Command("powershell", "/c", cmd).CombinedOutput()
if err != nil {
return false, fmt.Errorf("error getting disk state. cmd: %s, output: %s, error: %v", cmd, string(out), err)
}

sout := strings.TrimSpace(string(out))
isOffline, err := strconv.ParseBool(sout)
if err != nil {
return false, fmt.Errorf("error parsing disk state. output: %s, error: %v", sout, err)
}

return !isOffline, nil
}
7 changes: 7 additions & 0 deletions internal/server/disk/api_group_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions internal/server/disk/internal/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,24 @@ type DiskStatsRequest struct {
type DiskStatsResponse struct {
DiskSize int64
}

type SetAttachStateRequest struct {
// Disk device ID of the disk which state will change
DiskID string

// Online state to set for the disk. true for online, false for offline
IsOnline bool
}

type SetAttachStateResponse struct {
}

type GetAttachStateRequest struct {
// Disk device ID of the disk
DiskID string
}

type GetAttachStateResponse struct {
// Online state of the disk. true for online, false for offline
IsOnline bool
}
2 changes: 2 additions & 0 deletions internal/server/disk/internal/types_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading