Skip to content
Open
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
12 changes: 4 additions & 8 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,11 @@ jobs:
name: Build
runs-on: ubuntu-latest
steps:

- name: Set up Go 1.x
uses: actions/setup-go@v3
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: ^1.19
id: go

- name: Check out code into the Go module directory
uses: actions/checkout@v3
go-version-file: go.mod

- name: Build Test
run: |
Expand Down
95 changes: 95 additions & 0 deletions csi.proto
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@ service Controller {
rpc ControllerModifyVolume (ControllerModifyVolumeRequest)
returns (ControllerModifyVolumeResponse) {
}

rpc ControllerGetNodeInfo (ControllerGetNodeInfoRequest)
returns (ControllerGetNodeInfoResponse) {
option (alpha_method) = true;
}
}

service GroupController {
Expand Down Expand Up @@ -167,6 +172,11 @@ service Node {

rpc NodeGetInfo (NodeGetInfoRequest)
returns (NodeGetInfoResponse) {}

rpc NodeGetID (NodeGetIDRequest)
returns (NodeGetIDResponse) {
option (alpha_method) = true;
}
}
message GetPluginInfoRequest {
// Intentionally empty.
Expand Down Expand Up @@ -1043,6 +1053,56 @@ message ControllerModifyVolumeRequest {
message ControllerModifyVolumeResponse {
}

message ControllerGetNodeInfoRequest {
// The identifier of the node as understood by the SP.
// This field is REQUIRED.
// This field MUST match the node_id returned by `NodeGetInfo` or
// `NodeGetID`.
// This field overrides the general CSI size limit.
// The size of this field SHALL NOT exceed 256 bytes.
string node_id = 1;
}

message ControllerGetNodeInfoResponse {
// Maximum number of volumes that controller can publish to the node.
// If value is not set or zero CO SHALL decide how many volumes of
// this type can be published by the controller to the node. The
// plugin MUST NOT set negative values here.
// This field is OPTIONAL.
int64 max_volumes_per_node = 1;

// Specifies where (regions, zones, racks, etc.) the node is
// accessible from.
// A plugin that returns this field MUST also set the
// VOLUME_ACCESSIBILITY_CONSTRAINTS plugin capability.
// COs MAY use this information along with the topology information
// returned in CreateVolumeResponse to ensure that a given volume is
// accessible from a given node when scheduling workloads.
// This field is OPTIONAL. If it is not specified, the CO MAY assume
// the node is not subject to any topological constraint, and MAY
// schedule workloads that reference any volume V, such that there are
// no topological constraints declared for V.
//
// Example 1:
// accessible_topology =
// {"region": "R1", "zone": "Z2"}
// Indicates the node exists within the "region" "R1" and the "zone"
// "Z2".
Topology accessible_topology = 2;

// The volume IDs that are currently published to this node.
// These volumes may not be published by CO, but still occupy slots
// reported by max_volumes_per_node.
//
// This field is OPTIONAL. If provided, the CO SHALL combine these
// volumes with its own records (deduplicating as needed) when
// calculating available slots.
//
// The CO MUST NOT use these volume IDs for any purpose other than
// slot accounting. In particular, the CO MUST NOT attempt to
// unpublish or otherwise operate on volumes it did not publish.
repeated string published_volume_ids = 3;
}
message GetCapacityRequest {
// If specified, the Plugin SHALL report the capacity of the storage
// that can be used to provision volumes that satisfy ALL of the
Expand Down Expand Up @@ -1190,6 +1250,12 @@ message ControllerServiceCapability {
// Indicates the SP supports the GetSnapshot RPC.
// This enables COs to fetch an existing snapshot.
GET_SNAPSHOT = 15 [(alpha_enum_value) = true];

// Indicates the SP supports the ControllerGetNodeInfo RPC.
// This enables COs to fetch node topology and capacity
// information from the controller side, avoiding the need for
// cloud API credentials on the node side.
GET_NODE_INFO = 16 [(alpha_enum_value) = true];
}

Type type = 1;
Expand Down Expand Up @@ -1672,6 +1738,15 @@ message NodeServiceCapability {
// with provided volume group identifier during node stage
// or node publish RPC calls.
VOLUME_MOUNT_GROUP = 6;

// Indicates the SP supports the NodeGetID RPC.
// This enables COs to fetch only the node identifier from
// the node side without requiring cloud API credentials.
// The topology and capacity information can then be fetched
// via ControllerGetNodeInfo.
// If the SP supports GET_ID, it MUST also support
// GET_NODE_INFO controller capability.
GET_ID = 7 [(alpha_enum_value) = true];
}

Type type = 1;
Expand Down Expand Up @@ -1726,6 +1801,26 @@ message NodeGetInfoResponse {
// "Z2".
Topology accessible_topology = 3;
}
message NodeGetIDRequest {
// Intentionally empty.
}

message NodeGetIDResponse {
// The identifier of the node as understood by the SP.
// This field is REQUIRED.
// This field MUST contain enough information to uniquely identify
// this specific node vs all other nodes supported by this plugin.
// This field SHALL be used by the CO in subsequent calls, including
// `ControllerPublishVolume` and `ControllerGetNodeInfo`, to refer to
// this node.
// The SP is NOT responsible for global uniqueness of node_id across
// multiple SPs.
// This field overrides the general CSI size limit.
// The size of this field SHALL NOT exceed 256 bytes. The general
// CSI size limit, 128 byte, is RECOMMENDED for best backwards
// compatibility.
string node_id = 1;
}
message NodeExpandVolumeRequest {
// The ID of the volume. This field is REQUIRED.
string volume_id = 1;
Expand Down
6 changes: 6 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ module github.com/container-storage-interface/spec

go 1.24.0

tool (
google.golang.org/grpc/cmd/protoc-gen-go-grpc
google.golang.org/protobuf/cmd/protoc-gen-go
)

require (
google.golang.org/grpc v1.79.3
google.golang.org/protobuf v1.36.10
Expand All @@ -12,4 +17,5 @@ require (
golang.org/x/sys v0.39.0 // indirect
golang.org/x/text v0.32.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 // indirect
)
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,7 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=
google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 h1:rNBFJjBCOgVr9pWD7rs/knKL4FRTKgpZmsRfV214zcA=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0/go.mod h1:Dk1tviKTvMCz5tvh7t+fh94dhmQVHuCt2OzJB3CTW9Y=
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
1 change: 0 additions & 1 deletion lib/go/.gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/protoc
/protoc-gen-go
/csi.a
/.protoc
41 changes: 4 additions & 37 deletions lib/go/Makefile
Original file line number Diff line number Diff line change
@@ -1,25 +1,5 @@
all: build

########################################################################
## GOLANG ##
########################################################################

# If GOPATH isn't defined then set its default location.
ifeq (,$(strip $(GOPATH)))
GOPATH := $(HOME)/go
else
# If GOPATH is already set then update GOPATH to be its own
# first element.
GOPATH := $(word 1,$(subst :, ,$(GOPATH)))
endif
export GOPATH

GOBIN := $(shell go env GOBIN)
ifeq (,$(strip $(GOBIN)))
GOBIN := $(GOPATH)/bin
endif


########################################################################
## PROTOC ##
########################################################################
Expand All @@ -46,28 +26,14 @@ PROTOC_URL := https://github.com/protocolbuffers/protobuf/releases/download/v$(P
PROTOC_TMP_DIR := .protoc
PROTOC := $(PROTOC_TMP_DIR)/bin/protoc

$(GOBIN)/protoc-gen-go: ../../go.mod
go install google.golang.org/protobuf/cmd/protoc-gen-go
$(GOBIN)/protoc-gen-go-grpc:
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3.0

$(PROTOC):
-mkdir -p "$(PROTOC_TMP_DIR)" && \
curl -L $(PROTOC_URL) -o "$(PROTOC_TMP_DIR)/$(PROTOC_ZIP)" && \
unzip "$(PROTOC_TMP_DIR)/$(PROTOC_ZIP)" -d "$(PROTOC_TMP_DIR)" && \
chmod 0755 "$@"
stat "$@" > /dev/null 2>&1

PROTOC_ALL := $(GOBIN)/protoc-gen-go $(GOBIN)/protoc-gen-go-grpc $(PROTOC)

########################################################################
## PATH ##
########################################################################

# Update PATH with GOBIN. This enables the protoc binary to discover
# the protoc-gen-go binary
export PATH := $(GOBIN):$(PATH)

PROTOC_ALL := protoc-gen-go protoc-gen-go-grpc $(PROTOC)

########################################################################
## BUILD ##
Expand All @@ -78,9 +44,10 @@ CSI_GO := $(CSI_PKG_SUB)/csi.pb.go
CSI_GRPC := $(CSI_PKG_SUB)/csi_grpc.pb.go

# This recipe generates the go language bindings
$(CSI_GO) $(CSI_GRPC): $(CSI_PROTO) $(PROTOC_ALL)
$(CSI_GO) $(CSI_GRPC): $(CSI_PROTO) $(PROTOC_ALL) ../../go.mod
@mkdir -p "$(@D)"
$(PROTOC) -I../.. --go-grpc_out=$(CSI_PKG_SUB) --go_out=$(CSI_PKG_SUB) \
$(PROTOC) --plugin=./protoc-gen-go --plugin=./protoc-gen-go-grpc \
-I../.. --go-grpc_out=$(CSI_PKG_SUB) --go_out=$(CSI_PKG_SUB) \
--go_opt=paths=source_relative --go-grpc_opt=paths=source_relative \
"$(<F)"

Expand Down
Loading
Loading