├── VERSION ├── .gitignore ├── lib ├── go │ ├── .gitignore │ ├── csi.go │ ├── README.md │ ├── Makefile │ └── csi │ │ └── csi_grpc.pb.go ├── cxx │ └── Makefile └── README.md ├── CCLA.pdf ├── logo.png ├── .github ├── ISSUE_TEMPLATE │ ├── support.md │ ├── bug-report.md │ └── enhancement.md ├── workflows │ ├── codespell.yml │ └── build.yaml └── PULL_REQUEST_TEMPLATE.md ├── OWNERS ├── go.mod ├── README.md ├── Makefile ├── go.sum ├── CONTRIBUTING.md ├── LICENSE └── csi.proto /VERSION: -------------------------------------------------------------------------------- 1 | 1.13.0 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.tmp 2 | .DS_Store 3 | .build 4 | csi.a 5 | *.swp 6 | -------------------------------------------------------------------------------- /lib/go/.gitignore: -------------------------------------------------------------------------------- 1 | /protoc 2 | /protoc-gen-go 3 | /csi.a 4 | /.protoc 5 | -------------------------------------------------------------------------------- /CCLA.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/container-storage-interface/spec/HEAD/CCLA.pdf -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/container-storage-interface/spec/HEAD/logo.png -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/support.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Support Request 3 | about: Ask questions about this project 4 | 5 | --- 6 | 7 | -------------------------------------------------------------------------------- /lib/cxx/Makefile: -------------------------------------------------------------------------------- 1 | all: build 2 | 3 | build: 4 | @echo "cxx bindings & validation" 5 | 6 | clean: 7 | @echo "clean cxx" 8 | 9 | .PHONY: clean 10 | -------------------------------------------------------------------------------- /lib/README.md: -------------------------------------------------------------------------------- 1 | # CSI Validation Libraries 2 | This directory contains language bindings generated from the CSI [protobuf file](../csi.proto) used to validate the model and workflows of the CSI specification. 3 | -------------------------------------------------------------------------------- /lib/go/csi.go: -------------------------------------------------------------------------------- 1 | // Package csi is the Container Storage Interface (CSI) specification 2 | // repository. This package contains no functional code, and this file 3 | // exists only to make it possible to import this repository with a Go 4 | // dependency manager such as Dep (https://github.com/golang/dep). 5 | package csi 6 | -------------------------------------------------------------------------------- /OWNERS: -------------------------------------------------------------------------------- 1 | approvers: 2 | - saad-ali # Representing Kubernetes 3 | - bswartz # Representing Kubernetes 4 | - jieyu # Representing Mesos 5 | - jdef # Representing Mesos 6 | - anusha-ragunathan # Representing Docker 7 | - ddebroy # Representing Docker 8 | - julian-hj # Representing Cloud Foundry 9 | - paulcwarren # Representing Cloud Foundry 10 | reviewers: 11 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/container-storage-interface/spec 2 | 3 | go 1.23.0 4 | 5 | require ( 6 | google.golang.org/grpc v1.57.1 7 | google.golang.org/protobuf v1.33.0 8 | ) 9 | 10 | require ( 11 | github.com/golang/protobuf v1.5.4 // indirect 12 | golang.org/x/net v0.38.0 // indirect 13 | golang.org/x/sys v0.31.0 // indirect 14 | golang.org/x/text v0.23.0 // indirect 15 | google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 // indirect 16 | ) 17 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug Report 3 | about: Create a report to help us improve this project 4 | 5 | --- 6 | 7 | 9 | 10 | 11 | **What happened**: 12 | 13 | **What you expected to happen**: 14 | 15 | **How to reproduce it**: 16 | 17 | **Anything else we need to know?**: 18 | 19 | **Environment**: 20 | - CSI Spec version: 21 | - Others: 22 | -------------------------------------------------------------------------------- /.github/workflows/codespell.yml: -------------------------------------------------------------------------------- 1 | # GitHub Action to automate the identification of common misspellings in text files. 2 | # https://github.com/codespell-project/actions-codespell 3 | # https://github.com/codespell-project/codespell 4 | name: codespell 5 | on: [push, pull_request] 6 | jobs: 7 | codespell: 8 | name: Check for spelling errors 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v3 12 | - uses: codespell-project/actions-codespell@master 13 | with: 14 | check_filenames: true 15 | skip: ./.git,./.github/workflows/codespell.yml,.git,*.png,*.jpg,*.svg,*.sum,go.sum 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Container Storage Interface (CSI) Specification ![build status](https://github.com/container-storage-interface/spec/actions/workflows/build.yaml/badge.svg) 2 | 3 | ![CSI Logo](logo.png) 4 | 5 | This project contains the CSI [specification](spec.md) and [protobuf](csi.proto) files. 6 | 7 | ## CSI Adoption 8 | 9 | ### Container Orchestrators (CO) 10 | 11 | * [Cloud Foundry](https://github.com/cloudfoundry/csi-plugins-release/blob/master/CSI_SUPPORT.md) 12 | * [Kubernetes](https://kubernetes-csi.github.io/docs/) 13 | * [Mesos](http://mesos.apache.org/documentation/latest/csi/) 14 | * [Nomad](https://nomadproject.io/docs/internals/plugins/csi/) 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/enhancement.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Enhancement Request 3 | about: Suggest an idea for this project 4 | 5 | --- 6 | 7 | 8 | **Is your feature request related to a problem?/Why is this needed** 9 | 10 | 11 | **Describe the solution you'd like in detail** 12 | 13 | 14 | **Describe alternatives you've considered** 15 | 16 | 17 | **Additional context** 18 | 19 | -------------------------------------------------------------------------------- /.github/workflows/build.yaml: -------------------------------------------------------------------------------- 1 | name: Build Test 2 | 3 | on: 4 | pull_request: {} 5 | push: {} 6 | 7 | jobs: 8 | 9 | build: 10 | name: Build 11 | runs-on: ubuntu-latest 12 | steps: 13 | 14 | - name: Set up Go 1.x 15 | uses: actions/setup-go@v3 16 | with: 17 | go-version: ^1.19 18 | id: go 19 | 20 | - name: Check out code into the Go module directory 21 | uses: actions/checkout@v3 22 | 23 | - name: Build Test 24 | run: | 25 | touch spec.md # Ensure its timestamp is newer than any generated files 26 | make 27 | git diff --exit-code || (echo "Generated files are out of date. Please run 'make' and commit the changes." && exit 1) 28 | -------------------------------------------------------------------------------- /lib/go/README.md: -------------------------------------------------------------------------------- 1 | # CSI Go Validation 2 | 3 | This package is used to validate the CSI specification with Go language bindings. 4 | It is recommended to build this package inside `GOPATH`. 5 | 6 | ## Build Reference 7 | 8 | To validate the Go language bindings against the current specification use the following command: 9 | 10 | ```bash 11 | $ make 12 | ``` 13 | 14 | The above command will download the `protoc` and `protoc-gen-go` binaries if they are not present and then proceed to build the CSI Go language bindings. 15 | 16 | ### Environment Variables 17 | 18 | The following table lists the environment variables that can be used to influence the behavior of the Makefile: 19 | 20 | | Name | Default Value | Description | 21 | |------|---------------|-------------| 22 | | `PROTOC_VER` | `3.3.0` | The version of the protoc binary. | 23 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | **What type of PR is this?** 2 | 3 | **What this PR does / why we need it**: 4 | 5 | **Which issue(s) this PR fixes**: 6 | 11 | Fixes # 12 | 13 | **Special notes for your reviewer**: 14 | 15 | **Does this PR introduce an API-breaking change?**: 16 | 21 | ```release-note 22 | none 23 | ``` 24 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: build 2 | 3 | CSI_SPEC := spec.md 4 | CSI_PROTO := csi.proto 5 | ## Build go language bindings 6 | CSI_A := csi.a 7 | CSI_PKG := lib/go/csi 8 | 9 | # This is the target for building the CSI protobuf file. 10 | $(CSI_PROTO): $(CSI_SPEC) Makefile 11 | echo "// Code generated by make; DO NOT EDIT." > "$@" 12 | sed -n -e '/```protobuf$$/,/^```$$/ {//!p;}' $< >> "$@" 13 | 14 | build: check build_cpp build_go 15 | 16 | build_cpp: 17 | $(MAKE) -C lib/cxx 18 | 19 | $(CSI_PKG)/%.pb.go: $(CSI_PROTO) 20 | $(MAKE) -C lib/go 21 | 22 | $(CSI_A): $(CSI_PKG)/*.go 23 | go mod download 24 | go install ./$(CSI_PKG) 25 | go build -o "$@" ./$(CSI_PKG) 26 | 27 | build_go: $(CSI_A) 28 | 29 | clean: 30 | rm $(CSI_A) 31 | $(MAKE) -C lib/go $@ 32 | 33 | clobber: clean 34 | $(MAKE) -C lib/go $@ 35 | rm -f $(CSI_PROTO) 36 | 37 | # check generated files for violation of standards 38 | check: $(CSI_PROTO) 39 | awk '{ if (length > 72) print NR, $$0 }' $? | diff - /dev/null 40 | 41 | .PHONY: clean clobber check build_go build_cpp 42 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= 2 | github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= 3 | github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= 4 | github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 5 | golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= 6 | golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= 7 | golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= 8 | golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 9 | golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= 10 | golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= 11 | google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 h1:eSaPbMR4T7WfH9FvABk36NBMacoTUKdWCvV0dx+KfOg= 12 | google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5/go.mod h1:zBEcrKX2ZOcEkHWxBPAIvYUWOKKMIhYcmNiUIu2ji3I= 13 | google.golang.org/grpc v1.57.1 h1:upNTNqv0ES+2ZOOqACwVtS3Il8M12/+Hz41RCPzAjQg= 14 | google.golang.org/grpc v1.57.1/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= 15 | google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= 16 | google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= 17 | -------------------------------------------------------------------------------- /lib/go/Makefile: -------------------------------------------------------------------------------- 1 | all: build 2 | 3 | ######################################################################## 4 | ## GOLANG ## 5 | ######################################################################## 6 | 7 | # If GOPATH isn't defined then set its default location. 8 | ifeq (,$(strip $(GOPATH))) 9 | GOPATH := $(HOME)/go 10 | else 11 | # If GOPATH is already set then update GOPATH to be its own 12 | # first element. 13 | GOPATH := $(word 1,$(subst :, ,$(GOPATH))) 14 | endif 15 | export GOPATH 16 | 17 | GOBIN := $(shell go env GOBIN) 18 | ifeq (,$(strip $(GOBIN))) 19 | GOBIN := $(GOPATH)/bin 20 | endif 21 | 22 | 23 | ######################################################################## 24 | ## PROTOC ## 25 | ######################################################################## 26 | 27 | # Only set PROTOC_VER if it has an empty value. 28 | ifeq (,$(strip $(PROTOC_VER))) 29 | PROTOC_VER := 25.2 30 | endif 31 | 32 | PROTOC_OS := $(shell uname -s) 33 | ifeq (Darwin,$(PROTOC_OS)) 34 | PROTOC_OS := osx 35 | endif 36 | 37 | PROTOC_ARCH := $(shell uname -m) 38 | ifeq (i386,$(PROTOC_ARCH)) 39 | PROTOC_ARCH := x86_32 40 | else ifeq (arm64,$(PROTOC_ARCH)) 41 | PROTOC_ARCH := aarch_64 42 | endif 43 | 44 | PROTOC_ZIP := protoc-$(PROTOC_VER)-$(PROTOC_OS)-$(PROTOC_ARCH).zip 45 | PROTOC_URL := https://github.com/protocolbuffers/protobuf/releases/download/v$(PROTOC_VER)/$(PROTOC_ZIP) 46 | PROTOC_TMP_DIR := .protoc 47 | PROTOC := $(PROTOC_TMP_DIR)/bin/protoc 48 | 49 | $(GOBIN)/protoc-gen-go: ../../go.mod 50 | go install google.golang.org/protobuf/cmd/protoc-gen-go 51 | $(GOBIN)/protoc-gen-go-grpc: 52 | go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3.0 53 | 54 | $(PROTOC): 55 | -mkdir -p "$(PROTOC_TMP_DIR)" && \ 56 | curl -L $(PROTOC_URL) -o "$(PROTOC_TMP_DIR)/$(PROTOC_ZIP)" && \ 57 | unzip "$(PROTOC_TMP_DIR)/$(PROTOC_ZIP)" -d "$(PROTOC_TMP_DIR)" && \ 58 | chmod 0755 "$@" 59 | stat "$@" > /dev/null 2>&1 60 | 61 | PROTOC_ALL := $(GOBIN)/protoc-gen-go $(GOBIN)/protoc-gen-go-grpc $(PROTOC) 62 | 63 | ######################################################################## 64 | ## PATH ## 65 | ######################################################################## 66 | 67 | # Update PATH with GOBIN. This enables the protoc binary to discover 68 | # the protoc-gen-go binary 69 | export PATH := $(GOBIN):$(PATH) 70 | 71 | 72 | ######################################################################## 73 | ## BUILD ## 74 | ######################################################################## 75 | CSI_PROTO := ../../csi.proto 76 | CSI_PKG_SUB := csi 77 | CSI_GO := $(CSI_PKG_SUB)/csi.pb.go 78 | CSI_GRPC := $(CSI_PKG_SUB)/csi_grpc.pb.go 79 | 80 | # This recipe generates the go language bindings 81 | $(CSI_GO) $(CSI_GRPC): $(CSI_PROTO) $(PROTOC_ALL) 82 | @mkdir -p "$(@D)" 83 | $(PROTOC) -I../.. --go-grpc_out=$(CSI_PKG_SUB) --go_out=$(CSI_PKG_SUB) \ 84 | --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative \ 85 | "$( manifest = 3; 190 | } 191 | message GetPluginCapabilitiesRequest { 192 | // Intentionally empty. 193 | } 194 | 195 | message GetPluginCapabilitiesResponse { 196 | // All the capabilities that the controller service supports. This 197 | // field is OPTIONAL. 198 | repeated PluginCapability capabilities = 1; 199 | } 200 | 201 | // Specifies a capability of the plugin. 202 | message PluginCapability { 203 | message Service { 204 | enum Type { 205 | UNKNOWN = 0; 206 | // CONTROLLER_SERVICE indicates that the Plugin provides RPCs for 207 | // the ControllerService. Plugins SHOULD provide this capability. 208 | // In rare cases certain plugins MAY wish to omit the 209 | // ControllerService entirely from their implementation, but such 210 | // SHOULD NOT be the common case. 211 | // The presence of this capability determines whether the CO will 212 | // attempt to invoke the REQUIRED ControllerService RPCs, as well 213 | // as specific RPCs as indicated by ControllerGetCapabilities. 214 | CONTROLLER_SERVICE = 1; 215 | 216 | // VOLUME_ACCESSIBILITY_CONSTRAINTS indicates that the volumes for 217 | // this plugin MAY NOT be equally accessible by all nodes in the 218 | // cluster. The CO MUST use the topology information returned by 219 | // CreateVolumeRequest along with the topology information 220 | // returned by NodeGetInfo to ensure that a given volume is 221 | // accessible from a given node when scheduling workloads. 222 | VOLUME_ACCESSIBILITY_CONSTRAINTS = 2; 223 | 224 | // GROUP_CONTROLLER_SERVICE indicates that the Plugin provides 225 | // RPCs for operating on groups of volumes. Plugins MAY provide 226 | // this capability. 227 | // The presence of this capability determines whether the CO will 228 | // attempt to invoke the REQUIRED GroupController service RPCs, as 229 | // well as specific RPCs as indicated by 230 | // GroupControllerGetCapabilities. 231 | GROUP_CONTROLLER_SERVICE = 3; 232 | 233 | // SNAPSHOT_METADATA_SERVICE indicates that the Plugin provides 234 | // RPCs to retrieve metadata on the allocated blocks of a single 235 | // snapshot, or the changed blocks between a pair of snapshots of 236 | // the same block volume. 237 | // The presence of this capability determines whether the CO will 238 | // attempt to invoke the OPTIONAL SnapshotMetadata service RPCs. 239 | SNAPSHOT_METADATA_SERVICE = 4 [(alpha_enum_value) = true]; 240 | } 241 | Type type = 1; 242 | } 243 | 244 | message VolumeExpansion { 245 | enum Type { 246 | UNKNOWN = 0; 247 | 248 | // ONLINE indicates that volumes may be expanded when published to 249 | // a node. When a Plugin implements this capability it MUST 250 | // implement either the EXPAND_VOLUME controller capability or the 251 | // EXPAND_VOLUME node capability or both. When a plugin supports 252 | // ONLINE volume expansion and also has the EXPAND_VOLUME 253 | // controller capability then the plugin MUST support expansion of 254 | // volumes currently published and available on a node. When a 255 | // plugin supports ONLINE volume expansion and also has the 256 | // EXPAND_VOLUME node capability then the plugin MAY support 257 | // expansion of node-published volume via NodeExpandVolume. 258 | // 259 | // Example 1: Given a shared filesystem volume (e.g. GlusterFs), 260 | // the Plugin may set the ONLINE volume expansion capability and 261 | // implement ControllerExpandVolume but not NodeExpandVolume. 262 | // 263 | // Example 2: Given a block storage volume type (e.g. EBS), the 264 | // Plugin may set the ONLINE volume expansion capability and 265 | // implement both ControllerExpandVolume and NodeExpandVolume. 266 | // 267 | // Example 3: Given a Plugin that supports volume expansion only 268 | // upon a node, the Plugin may set the ONLINE volume 269 | // expansion capability and implement NodeExpandVolume but not 270 | // ControllerExpandVolume. 271 | ONLINE = 1; 272 | 273 | // OFFLINE indicates that volumes currently published and 274 | // available on a node SHALL NOT be expanded via 275 | // ControllerExpandVolume. When a plugin supports OFFLINE volume 276 | // expansion it MUST implement either the EXPAND_VOLUME controller 277 | // capability or both the EXPAND_VOLUME controller capability and 278 | // the EXPAND_VOLUME node capability. 279 | // 280 | // Example 1: Given a block storage volume type (e.g. Azure Disk) 281 | // that does not support expansion of "node-attached" (i.e. 282 | // controller-published) volumes, the Plugin may indicate 283 | // OFFLINE volume expansion support and implement both 284 | // ControllerExpandVolume and NodeExpandVolume. 285 | OFFLINE = 2; 286 | } 287 | Type type = 1; 288 | } 289 | 290 | oneof type { 291 | // Service that the plugin supports. 292 | Service service = 1; 293 | VolumeExpansion volume_expansion = 2; 294 | } 295 | } 296 | message ProbeRequest { 297 | // Intentionally empty. 298 | } 299 | 300 | message ProbeResponse { 301 | // Readiness allows a plugin to report its initialization status back 302 | // to the CO. Initialization for some plugins MAY be time consuming 303 | // and it is important for a CO to distinguish between the following 304 | // cases: 305 | // 306 | // 1) The plugin is in an unhealthy state and MAY need restarting. In 307 | // this case a gRPC error code SHALL be returned. 308 | // 2) The plugin is still initializing, but is otherwise perfectly 309 | // healthy. In this case a successful response SHALL be returned 310 | // with a readiness value of `false`. Calls to the plugin's 311 | // Controller and/or Node services MAY fail due to an incomplete 312 | // initialization state. 313 | // 3) The plugin has finished initializing and is ready to service 314 | // calls to its Controller and/or Node services. A successful 315 | // response is returned with a readiness value of `true`. 316 | // 317 | // This field is OPTIONAL. If not present, the caller SHALL assume 318 | // that the plugin is in a ready state and is accepting calls to its 319 | // Controller and/or Node services (according to the plugin's reported 320 | // capabilities). 321 | .google.protobuf.BoolValue ready = 1; 322 | } 323 | message CreateVolumeRequest { 324 | // The suggested name for the storage space. This field is REQUIRED. 325 | // It serves two purposes: 326 | // 1) Idempotency - This name is generated by the CO to achieve 327 | // idempotency. The Plugin SHOULD ensure that multiple 328 | // `CreateVolume` calls for the same name do not result in more 329 | // than one piece of storage provisioned corresponding to that 330 | // name. If a Plugin is unable to enforce idempotency, the CO's 331 | // error recovery logic could result in multiple (unused) volumes 332 | // being provisioned. 333 | // In the case of error, the CO MUST handle the gRPC error codes 334 | // per the recovery behavior defined in the "CreateVolume Errors" 335 | // section below. 336 | // The CO is responsible for cleaning up volumes it provisioned 337 | // that it no longer needs. If the CO is uncertain whether a volume 338 | // was provisioned or not when a `CreateVolume` call fails, the CO 339 | // MAY call `CreateVolume` again, with the same name, to ensure the 340 | // volume exists and to retrieve the volume's `volume_id` (unless 341 | // otherwise prohibited by "CreateVolume Errors"). 342 | // 2) Suggested name - Some storage systems allow callers to specify 343 | // an identifier by which to refer to the newly provisioned 344 | // storage. If a storage system supports this, it can optionally 345 | // use this name as the identifier for the new volume. 346 | // Any Unicode string that conforms to the length limit is allowed 347 | // except those containing the following banned characters: 348 | // U+0000-U+0008, U+000B, U+000C, U+000E-U+001F, U+007F-U+009F. 349 | // (These are control characters other than commonly used whitespace.) 350 | string name = 1; 351 | 352 | // This field is OPTIONAL. This allows the CO to specify the capacity 353 | // requirement of the volume to be provisioned. If not specified, the 354 | // Plugin MAY choose an implementation-defined capacity range. If 355 | // specified it MUST always be honored, even when creating volumes 356 | // from a source; which MAY force some backends to internally extend 357 | // the volume after creating it. 358 | CapacityRange capacity_range = 2; 359 | 360 | // The capabilities that the provisioned volume MUST have. SP MUST 361 | // provision a volume that will satisfy ALL of the capabilities 362 | // specified in this list. Otherwise SP MUST return the appropriate 363 | // gRPC error code. 364 | // The Plugin MUST assume that the CO MAY use the provisioned volume 365 | // with ANY of the capabilities specified in this list. 366 | // For example, a CO MAY specify two volume capabilities: one with 367 | // access mode SINGLE_NODE_WRITER and another with access mode 368 | // MULTI_NODE_READER_ONLY. In this case, the SP MUST verify that the 369 | // provisioned volume can be used in either mode. 370 | // This also enables the CO to do early validation: If ANY of the 371 | // specified volume capabilities are not supported by the SP, the call 372 | // MUST return the appropriate gRPC error code. 373 | // This field is REQUIRED. 374 | repeated VolumeCapability volume_capabilities = 3; 375 | 376 | // Plugin specific creation-time parameters passed in as opaque 377 | // key-value pairs. This field is OPTIONAL. The Plugin is responsible 378 | // for parsing and validating these parameters. COs will treat 379 | // these as opaque. 380 | map parameters = 4; 381 | 382 | // Secrets required by plugin to complete volume creation request. 383 | // This field is OPTIONAL. Refer to the `Secrets Requirements` 384 | // section on how to use this field. 385 | map secrets = 5 [(csi_secret) = true]; 386 | 387 | // If specified, the new volume will be pre-populated with data from 388 | // this source. This field is OPTIONAL. 389 | VolumeContentSource volume_content_source = 6; 390 | 391 | // Specifies where (regions, zones, racks, etc.) the provisioned 392 | // volume MUST be accessible from. 393 | // An SP SHALL advertise the requirements for topological 394 | // accessibility information in documentation. COs SHALL only specify 395 | // topological accessibility information supported by the SP. 396 | // This field is OPTIONAL. 397 | // This field SHALL NOT be specified unless the SP has the 398 | // VOLUME_ACCESSIBILITY_CONSTRAINTS plugin capability. 399 | // If this field is not specified and the SP has the 400 | // VOLUME_ACCESSIBILITY_CONSTRAINTS plugin capability, the SP MAY 401 | // choose where the provisioned volume is accessible from. 402 | TopologyRequirement accessibility_requirements = 7; 403 | 404 | // Plugin specific creation-time parameters passed in as opaque 405 | // key-value pairs. These mutable_parameteres MAY also be 406 | // changed during the lifetime of the volume via a subsequent 407 | // `ControllerModifyVolume` RPC. This field is OPTIONAL. 408 | // The Plugin is responsible for parsing and validating these 409 | // parameters. COs will treat these as opaque. 410 | 411 | // Plugins MUST treat these 412 | // as if they take precedence over the parameters field. 413 | // This field SHALL NOT be specified unless the SP has the 414 | // MODIFY_VOLUME plugin capability. 415 | map mutable_parameters = 8; 416 | } 417 | 418 | // Specifies what source the volume will be created from. One of the 419 | // type fields MUST be specified. 420 | message VolumeContentSource { 421 | message SnapshotSource { 422 | // Contains identity information for the existing source snapshot. 423 | // This field is REQUIRED. Plugin is REQUIRED to support creating 424 | // volume from snapshot if it supports the capability 425 | // CREATE_DELETE_SNAPSHOT. 426 | string snapshot_id = 1; 427 | } 428 | 429 | message VolumeSource { 430 | // Contains identity information for the existing source volume. 431 | // This field is REQUIRED. Plugins reporting CLONE_VOLUME 432 | // capability MUST support creating a volume from another volume. 433 | string volume_id = 1; 434 | } 435 | 436 | oneof type { 437 | SnapshotSource snapshot = 1; 438 | VolumeSource volume = 2; 439 | } 440 | } 441 | 442 | message CreateVolumeResponse { 443 | // Contains all attributes of the newly created volume that are 444 | // relevant to the CO along with information required by the Plugin 445 | // to uniquely identify the volume. This field is REQUIRED. 446 | Volume volume = 1; 447 | } 448 | 449 | // Specify a capability of a volume. 450 | message VolumeCapability { 451 | // Indicate that the volume will be accessed via the block device API. 452 | message BlockVolume { 453 | // Intentionally empty, for now. 454 | } 455 | 456 | // Indicate that the volume will be accessed via the filesystem API. 457 | message MountVolume { 458 | // The filesystem type. This field is OPTIONAL. 459 | // An empty string is equal to an unspecified field value. 460 | string fs_type = 1; 461 | 462 | // The mount options that can be used for the volume. This field is 463 | // OPTIONAL. `mount_flags` MAY contain sensitive information. 464 | // Therefore, the CO and the Plugin MUST NOT leak this information 465 | // to untrusted entities. The total size of this repeated field 466 | // SHALL NOT exceed 4 KiB. 467 | repeated string mount_flags = 2; 468 | 469 | // If SP has VOLUME_MOUNT_GROUP node capability and CO provides 470 | // this field then SP MUST ensure that the volume_mount_group 471 | // parameter is passed as the group identifier to the underlying 472 | // operating system mount system call, with the understanding 473 | // that the set of available mount call parameters and/or 474 | // mount implementations may vary across operating systems. 475 | // Additionally, new file and/or directory entries written to 476 | // the underlying filesystem SHOULD be permission-labeled in such a 477 | // manner, unless otherwise modified by a workload, that they are 478 | // both readable and writable by said mount group identifier. 479 | // This is an OPTIONAL field. 480 | string volume_mount_group = 3; 481 | } 482 | 483 | // Specify how a volume can be accessed. 484 | message AccessMode { 485 | enum Mode { 486 | UNKNOWN = 0; 487 | 488 | // Can only be published once as read/write on a single node, at 489 | // any given time. 490 | SINGLE_NODE_WRITER = 1; 491 | 492 | // Can only be published once as readonly on a single node, at 493 | // any given time. 494 | SINGLE_NODE_READER_ONLY = 2; 495 | 496 | // Can be published as readonly at multiple nodes simultaneously. 497 | MULTI_NODE_READER_ONLY = 3; 498 | 499 | // Can be published at multiple nodes simultaneously. Only one of 500 | // the node can be used as read/write. The rest will be readonly. 501 | MULTI_NODE_SINGLE_WRITER = 4; 502 | 503 | // Can be published as read/write at multiple nodes 504 | // simultaneously. 505 | MULTI_NODE_MULTI_WRITER = 5; 506 | 507 | // Can only be published once as read/write at a single workload 508 | // on a single node, at any given time. SHOULD be used instead of 509 | // SINGLE_NODE_WRITER for COs using the experimental 510 | // SINGLE_NODE_MULTI_WRITER capability. 511 | SINGLE_NODE_SINGLE_WRITER = 6 [(alpha_enum_value) = true]; 512 | 513 | // Can be published as read/write at multiple workloads on a 514 | // single node simultaneously. SHOULD be used instead of 515 | // SINGLE_NODE_WRITER for COs using the experimental 516 | // SINGLE_NODE_MULTI_WRITER capability. 517 | SINGLE_NODE_MULTI_WRITER = 7 [(alpha_enum_value) = true]; 518 | } 519 | 520 | // This field is REQUIRED. 521 | Mode mode = 1; 522 | } 523 | 524 | // Specifies what API the volume will be accessed using. One of the 525 | // following fields MUST be specified. 526 | oneof access_type { 527 | BlockVolume block = 1; 528 | MountVolume mount = 2; 529 | } 530 | 531 | // This is a REQUIRED field. 532 | AccessMode access_mode = 3; 533 | } 534 | 535 | // The capacity of the storage space in bytes. To specify an exact size, 536 | // `required_bytes` and `limit_bytes` SHALL be set to the same value. At 537 | // least one of the these fields MUST be specified. 538 | message CapacityRange { 539 | // Volume MUST be at least this big. This field is OPTIONAL. 540 | // A value of 0 is equal to an unspecified field value. 541 | // The value of this field MUST NOT be negative. 542 | int64 required_bytes = 1; 543 | 544 | // Volume MUST not be bigger than this. This field is OPTIONAL. 545 | // A value of 0 is equal to an unspecified field value. 546 | // The value of this field MUST NOT be negative. 547 | int64 limit_bytes = 2; 548 | } 549 | 550 | // Information about a specific volume. 551 | message Volume { 552 | // The capacity of the volume in bytes. This field is OPTIONAL. If not 553 | // set (value of 0), it indicates that the capacity of the volume is 554 | // unknown (e.g., NFS share). 555 | // The value of this field MUST NOT be negative. 556 | int64 capacity_bytes = 1; 557 | 558 | // The identifier for this volume, generated by the plugin. 559 | // This field is REQUIRED. 560 | // This field MUST contain enough information to uniquely identify 561 | // this specific volume vs all other volumes supported by this plugin. 562 | // This field SHALL be used by the CO in subsequent calls to refer to 563 | // this volume. 564 | // The SP is NOT responsible for global uniqueness of volume_id across 565 | // multiple SPs. 566 | string volume_id = 2; 567 | 568 | // Opaque static properties of the volume. SP MAY use this field to 569 | // ensure subsequent volume validation and publishing calls have 570 | // contextual information. 571 | // The contents of this field SHALL be opaque to a CO. 572 | // The contents of this field SHALL NOT be mutable. 573 | // The contents of this field SHALL be safe for the CO to cache. 574 | // The contents of this field SHOULD NOT contain sensitive 575 | // information. 576 | // The contents of this field SHOULD NOT be used for uniquely 577 | // identifying a volume. The `volume_id` alone SHOULD be sufficient to 578 | // identify the volume. 579 | // A volume uniquely identified by `volume_id` SHALL always report the 580 | // same volume_context. 581 | // This field is OPTIONAL and when present MUST be passed to volume 582 | // validation and publishing calls. 583 | map volume_context = 3; 584 | 585 | // If specified, indicates that the volume is not empty and is 586 | // pre-populated with data from the specified source. 587 | // This field is OPTIONAL. 588 | VolumeContentSource content_source = 4; 589 | 590 | // Specifies where (regions, zones, racks, etc.) the provisioned 591 | // volume is accessible from. 592 | // A plugin that returns this field MUST also set the 593 | // VOLUME_ACCESSIBILITY_CONSTRAINTS plugin capability. 594 | // An SP MAY specify multiple topologies to indicate the volume is 595 | // accessible from multiple locations. 596 | // COs MAY use this information along with the topology information 597 | // returned by NodeGetInfo to ensure that a given volume is accessible 598 | // from a given node when scheduling workloads. 599 | // This field is OPTIONAL. If it is not specified, the CO MAY assume 600 | // the volume is equally accessible from all nodes in the cluster and 601 | // MAY schedule workloads referencing the volume on any available 602 | // node. 603 | // 604 | // Example 1: 605 | // accessible_topology = {"region": "R1", "zone": "Z2"} 606 | // Indicates a volume accessible only from the "region" "R1" and the 607 | // "zone" "Z2". 608 | // 609 | // Example 2: 610 | // accessible_topology = 611 | // {"region": "R1", "zone": "Z2"}, 612 | // {"region": "R1", "zone": "Z3"} 613 | // Indicates a volume accessible from both "zone" "Z2" and "zone" "Z3" 614 | // in the "region" "R1". 615 | repeated Topology accessible_topology = 5; 616 | } 617 | 618 | message TopologyRequirement { 619 | // Specifies the list of topologies the provisioned volume MUST be 620 | // accessible from. 621 | // This field is OPTIONAL. If TopologyRequirement is specified either 622 | // requisite or preferred or both MUST be specified. 623 | // 624 | // If requisite is specified, the provisioned volume MUST be 625 | // accessible from at least one of the requisite topologies. 626 | // 627 | // Given 628 | // x = number of topologies provisioned volume is accessible from 629 | // n = number of requisite topologies 630 | // The CO MUST ensure n >= 1. The SP MUST ensure x >= 1 631 | // If x==n, then the SP MUST make the provisioned volume available to 632 | // all topologies from the list of requisite topologies. If it is 633 | // unable to do so, the SP MUST fail the CreateVolume call. 634 | // For example, if a volume should be accessible from a single zone, 635 | // and requisite = 636 | // {"region": "R1", "zone": "Z2"} 637 | // then the provisioned volume MUST be accessible from the "region" 638 | // "R1" and the "zone" "Z2". 639 | // Similarly, if a volume should be accessible from two zones, and 640 | // requisite = 641 | // {"region": "R1", "zone": "Z2"}, 642 | // {"region": "R1", "zone": "Z3"} 643 | // then the provisioned volume MUST be accessible from the "region" 644 | // "R1" and both "zone" "Z2" and "zone" "Z3". 645 | // 646 | // If xn, then the SP MUST make the provisioned volume available from 665 | // all topologies from the list of requisite topologies and MAY choose 666 | // the remaining x-n unique topologies from the list of all possible 667 | // topologies. If it is unable to do so, the SP MUST fail the 668 | // CreateVolume call. 669 | // For example, if a volume should be accessible from two zones, and 670 | // requisite = 671 | // {"region": "R1", "zone": "Z2"} 672 | // then the provisioned volume MUST be accessible from the "region" 673 | // "R1" and the "zone" "Z2" and the SP may select the second zone 674 | // independently, e.g. "R1/Z4". 675 | repeated Topology requisite = 1; 676 | 677 | // Specifies the list of topologies the CO would prefer the volume to 678 | // be provisioned in. 679 | // 680 | // This field is OPTIONAL. If TopologyRequirement is specified either 681 | // requisite or preferred or both MUST be specified. 682 | // 683 | // An SP MUST attempt to make the provisioned volume available using 684 | // the preferred topologies in order from first to last. 685 | // 686 | // If requisite is specified, all topologies in preferred list MUST 687 | // also be present in the list of requisite topologies. 688 | // 689 | // If the SP is unable to to make the provisioned volume available 690 | // from any of the preferred topologies, the SP MAY choose a topology 691 | // from the list of requisite topologies. 692 | // If the list of requisite topologies is not specified, then the SP 693 | // MAY choose from the list of all possible topologies. 694 | // If the list of requisite topologies is specified and the SP is 695 | // unable to to make the provisioned volume available from any of the 696 | // requisite topologies it MUST fail the CreateVolume call. 697 | // 698 | // Example 1: 699 | // Given a volume should be accessible from a single zone, and 700 | // requisite = 701 | // {"region": "R1", "zone": "Z2"}, 702 | // {"region": "R1", "zone": "Z3"} 703 | // preferred = 704 | // {"region": "R1", "zone": "Z3"} 705 | // then the SP SHOULD first attempt to make the provisioned volume 706 | // available from "zone" "Z3" in the "region" "R1" and fall back to 707 | // "zone" "Z2" in the "region" "R1" if that is not possible. 708 | // 709 | // Example 2: 710 | // Given a volume should be accessible from a single zone, and 711 | // requisite = 712 | // {"region": "R1", "zone": "Z2"}, 713 | // {"region": "R1", "zone": "Z3"}, 714 | // {"region": "R1", "zone": "Z4"}, 715 | // {"region": "R1", "zone": "Z5"} 716 | // preferred = 717 | // {"region": "R1", "zone": "Z4"}, 718 | // {"region": "R1", "zone": "Z2"} 719 | // then the SP SHOULD first attempt to make the provisioned volume 720 | // accessible from "zone" "Z4" in the "region" "R1" and fall back to 721 | // "zone" "Z2" in the "region" "R1" if that is not possible. If that 722 | // is not possible, the SP may choose between either the "zone" 723 | // "Z3" or "Z5" in the "region" "R1". 724 | // 725 | // Example 3: 726 | // Given a volume should be accessible from TWO zones (because an 727 | // opaque parameter in CreateVolumeRequest, for example, specifies 728 | // the volume is accessible from two zones, aka synchronously 729 | // replicated), and 730 | // requisite = 731 | // {"region": "R1", "zone": "Z2"}, 732 | // {"region": "R1", "zone": "Z3"}, 733 | // {"region": "R1", "zone": "Z4"}, 734 | // {"region": "R1", "zone": "Z5"} 735 | // preferred = 736 | // {"region": "R1", "zone": "Z5"}, 737 | // {"region": "R1", "zone": "Z3"} 738 | // then the SP SHOULD first attempt to make the provisioned volume 739 | // accessible from the combination of the two "zones" "Z5" and "Z3" in 740 | // the "region" "R1". If that's not possible, it should fall back to 741 | // a combination of "Z5" and other possibilities from the list of 742 | // requisite. If that's not possible, it should fall back to a 743 | // combination of "Z3" and other possibilities from the list of 744 | // requisite. If that's not possible, it should fall back to a 745 | // combination of other possibilities from the list of requisite. 746 | repeated Topology preferred = 2; 747 | } 748 | 749 | // Topology is a map of topological domains to topological segments. 750 | // A topological domain is a sub-division of a cluster, like "region", 751 | // "zone", "rack", etc. 752 | // A topological segment is a specific instance of a topological domain, 753 | // like "zone3", "rack3", etc. 754 | // For example {"com.company/zone": "Z1", "com.company/rack": "R3"} 755 | // Valid keys have two segments: an OPTIONAL prefix and name, separated 756 | // by a slash (/), for example: "com.company.example/zone". 757 | // The key name segment is REQUIRED. The prefix is OPTIONAL. 758 | // The key name MUST be 63 characters or less, begin and end with an 759 | // alphanumeric character ([a-z0-9A-Z]), and contain only dashes (-), 760 | // underscores (_), dots (.), or alphanumerics in between, for example 761 | // "zone". 762 | // The key prefix MUST be 63 characters or less, begin and end with a 763 | // lower-case alphanumeric character ([a-z0-9]), contain only 764 | // dashes (-), dots (.), or lower-case alphanumerics in between, and 765 | // follow domain name notation format 766 | // (https://tools.ietf.org/html/rfc1035#section-2.3.1). 767 | // The key prefix SHOULD include the plugin's host company name and/or 768 | // the plugin name, to minimize the possibility of collisions with keys 769 | // from other plugins. 770 | // If a key prefix is specified, it MUST be identical across all 771 | // topology keys returned by the SP (across all RPCs). 772 | // Keys MUST be case-insensitive. Meaning the keys "Zone" and "zone" 773 | // MUST not both exist. 774 | // Each value (topological segment) MUST contain 1 or more strings. 775 | // Each string MUST be 63 characters or less and begin and end with an 776 | // alphanumeric character with '-', '_', '.', or alphanumerics in 777 | // between. 778 | message Topology { 779 | map segments = 1; 780 | } 781 | message DeleteVolumeRequest { 782 | // The ID of the volume to be deprovisioned. 783 | // This field is REQUIRED. 784 | string volume_id = 1; 785 | 786 | // Secrets required by plugin to complete volume deletion request. 787 | // This field is OPTIONAL. Refer to the `Secrets Requirements` 788 | // section on how to use this field. 789 | map secrets = 2 [(csi_secret) = true]; 790 | } 791 | 792 | message DeleteVolumeResponse { 793 | // Intentionally empty. 794 | } 795 | message ControllerPublishVolumeRequest { 796 | // The ID of the volume to be used on a node. 797 | // This field is REQUIRED. 798 | string volume_id = 1; 799 | 800 | // The ID of the node. This field is REQUIRED. The CO SHALL set this 801 | // field to match the node ID returned by `NodeGetInfo`. 802 | string node_id = 2; 803 | 804 | // Volume capability describing how the CO intends to use this volume. 805 | // SP MUST ensure the CO can use the published volume as described. 806 | // Otherwise SP MUST return the appropriate gRPC error code. 807 | // This is a REQUIRED field. 808 | VolumeCapability volume_capability = 3; 809 | 810 | // Indicates SP MUST publish the volume in readonly mode. 811 | // CO MUST set this field to false if SP does not have the 812 | // PUBLISH_READONLY controller capability. 813 | // This is a REQUIRED field. 814 | bool readonly = 4; 815 | 816 | // Secrets required by plugin to complete controller publish volume 817 | // request. This field is OPTIONAL. Refer to the 818 | // `Secrets Requirements` section on how to use this field. 819 | map secrets = 5 [(csi_secret) = true]; 820 | 821 | // Volume context as returned by SP in 822 | // CreateVolumeResponse.Volume.volume_context. 823 | // This field is OPTIONAL and MUST match the volume_context of the 824 | // volume identified by `volume_id`. 825 | map volume_context = 6; 826 | } 827 | 828 | message ControllerPublishVolumeResponse { 829 | // Opaque static publish properties of the volume. SP MAY use this 830 | // field to ensure subsequent `NodeStageVolume` or `NodePublishVolume` 831 | // calls calls have contextual information. 832 | // The contents of this field SHALL be opaque to a CO. 833 | // The contents of this field SHALL NOT be mutable. 834 | // The contents of this field SHALL be safe for the CO to cache. 835 | // The contents of this field SHOULD NOT contain sensitive 836 | // information. 837 | // The contents of this field SHOULD NOT be used for uniquely 838 | // identifying a volume. The `volume_id` alone SHOULD be sufficient to 839 | // identify the volume. 840 | // This field is OPTIONAL and when present MUST be passed to 841 | // subsequent `NodeStageVolume` or `NodePublishVolume` calls 842 | map publish_context = 1; 843 | } 844 | message ControllerUnpublishVolumeRequest { 845 | // The ID of the volume. This field is REQUIRED. 846 | string volume_id = 1; 847 | 848 | // The ID of the node. This field is OPTIONAL. The CO SHOULD set this 849 | // field to match the node ID returned by `NodeGetInfo` or leave it 850 | // unset. If the value is set, the SP MUST unpublish the volume from 851 | // the specified node. If the value is unset, the SP MUST unpublish 852 | // the volume from all nodes it is published to. 853 | string node_id = 2; 854 | 855 | // Secrets required by plugin to complete controller unpublish volume 856 | // request. This SHOULD be the same secrets passed to the 857 | // ControllerPublishVolume call for the specified volume. 858 | // This field is OPTIONAL. Refer to the `Secrets Requirements` 859 | // section on how to use this field. 860 | map secrets = 3 [(csi_secret) = true]; 861 | } 862 | 863 | message ControllerUnpublishVolumeResponse { 864 | // Intentionally empty. 865 | } 866 | message ValidateVolumeCapabilitiesRequest { 867 | // The ID of the volume to check. This field is REQUIRED. 868 | string volume_id = 1; 869 | 870 | // Volume context as returned by SP in 871 | // CreateVolumeResponse.Volume.volume_context. 872 | // This field is OPTIONAL and MUST match the volume_context of the 873 | // volume identified by `volume_id`. 874 | map volume_context = 2; 875 | 876 | // The capabilities that the CO wants to check for the volume. This 877 | // call SHALL return "confirmed" only if all the volume capabilities 878 | // specified below are supported. This field is REQUIRED. 879 | repeated VolumeCapability volume_capabilities = 3; 880 | 881 | // See CreateVolumeRequest.parameters. 882 | // This field is OPTIONAL. 883 | map parameters = 4; 884 | 885 | // Secrets required by plugin to complete volume validation request. 886 | // This field is OPTIONAL. Refer to the `Secrets Requirements` 887 | // section on how to use this field. 888 | map secrets = 5 [(csi_secret) = true]; 889 | 890 | // See CreateVolumeRequest.mutable_parameters. 891 | // This field is OPTIONAL. 892 | map mutable_parameters = 6; 893 | } 894 | 895 | message ValidateVolumeCapabilitiesResponse { 896 | message Confirmed { 897 | // Volume context validated by the plugin. 898 | // This field is OPTIONAL. 899 | map volume_context = 1; 900 | 901 | // Volume capabilities supported by the plugin. 902 | // This field is REQUIRED. 903 | repeated VolumeCapability volume_capabilities = 2; 904 | 905 | // The volume creation parameters validated by the plugin. 906 | // This field is OPTIONAL. 907 | map parameters = 3; 908 | 909 | // The volume creation mutable_parameters validated by the plugin. 910 | // This field is OPTIONAL. 911 | map mutable_parameters = 4; 912 | } 913 | 914 | // Confirmed indicates to the CO the set of capabilities that the 915 | // plugin has validated. This field SHALL only be set to a non-empty 916 | // value for successful validation responses. 917 | // For successful validation responses, the CO SHALL compare the 918 | // fields of this message to the originally requested capabilities in 919 | // order to guard against an older plugin reporting "valid" for newer 920 | // capability fields that it does not yet understand. 921 | // This field is OPTIONAL. 922 | Confirmed confirmed = 1; 923 | 924 | // Message to the CO if `confirmed` above is empty. This field is 925 | // OPTIONAL. 926 | // An empty string is equal to an unspecified field value. 927 | string message = 2; 928 | } 929 | message ListVolumesRequest { 930 | // If specified (non-zero value), the Plugin MUST NOT return more 931 | // entries than this number in the response. If the actual number of 932 | // entries is more than this number, the Plugin MUST set `next_token` 933 | // in the response which can be used to get the next page of entries 934 | // in the subsequent `ListVolumes` call. This field is OPTIONAL. If 935 | // not specified (zero value), it means there is no restriction on the 936 | // number of entries that can be returned. 937 | // The value of this field MUST NOT be negative. 938 | int32 max_entries = 1; 939 | 940 | // A token to specify where to start paginating. Set this field to 941 | // `next_token` returned by a previous `ListVolumes` call to get the 942 | // next page of entries. This field is OPTIONAL. 943 | // An empty string is equal to an unspecified field value. 944 | string starting_token = 2; 945 | } 946 | 947 | message ListVolumesResponse { 948 | message VolumeStatus{ 949 | // A list of all `node_id` of nodes that the volume in this entry 950 | // is controller published on. 951 | // This field is OPTIONAL. If it is not specified and the SP has 952 | // the LIST_VOLUMES_PUBLISHED_NODES controller capability, the CO 953 | // MAY assume the volume is not controller published to any nodes. 954 | // If the field is not specified and the SP does not have the 955 | // LIST_VOLUMES_PUBLISHED_NODES controller capability, the CO MUST 956 | // not interpret this field. 957 | // published_node_ids MAY include nodes not published to or 958 | // reported by the SP. The CO MUST be resilient to that. 959 | repeated string published_node_ids = 1; 960 | 961 | // Information about the current condition of the volume. 962 | // This field is OPTIONAL. 963 | // This field MUST be specified if the 964 | // VOLUME_CONDITION controller capability is supported. 965 | VolumeCondition volume_condition = 2 [(alpha_field) = true]; 966 | } 967 | 968 | message Entry { 969 | // This field is REQUIRED 970 | Volume volume = 1; 971 | 972 | // This field is OPTIONAL. This field MUST be specified if the 973 | // LIST_VOLUMES_PUBLISHED_NODES controller capability is 974 | // supported. 975 | VolumeStatus status = 2; 976 | } 977 | 978 | repeated Entry entries = 1; 979 | 980 | // This token allows you to get the next page of entries for 981 | // `ListVolumes` request. If the number of entries is larger than 982 | // `max_entries`, use the `next_token` as a value for the 983 | // `starting_token` field in the next `ListVolumes` request. This 984 | // field is OPTIONAL. 985 | // An empty string is equal to an unspecified field value. 986 | string next_token = 2; 987 | } 988 | message ControllerGetVolumeRequest { 989 | option (alpha_message) = true; 990 | 991 | // The ID of the volume to fetch current volume information for. 992 | // This field is REQUIRED. 993 | string volume_id = 1; 994 | } 995 | 996 | message ControllerGetVolumeResponse { 997 | option (alpha_message) = true; 998 | 999 | message VolumeStatus{ 1000 | // A list of all the `node_id` of nodes that this volume is 1001 | // controller published on. 1002 | // This field is OPTIONAL. 1003 | // This field MUST be specified if the LIST_VOLUMES_PUBLISHED_NODES 1004 | // controller capability is supported. 1005 | // published_node_ids MAY include nodes not published to or 1006 | // reported by the SP. The CO MUST be resilient to that. 1007 | repeated string published_node_ids = 1; 1008 | 1009 | // Information about the current condition of the volume. 1010 | // This field is OPTIONAL. 1011 | // This field MUST be specified if the 1012 | // VOLUME_CONDITION controller capability is supported. 1013 | VolumeCondition volume_condition = 2; 1014 | } 1015 | 1016 | // This field is REQUIRED 1017 | Volume volume = 1; 1018 | 1019 | // This field is REQUIRED. 1020 | VolumeStatus status = 2; 1021 | } 1022 | message ControllerModifyVolumeRequest { 1023 | // Contains identity information for the existing volume. 1024 | // This field is REQUIRED. 1025 | string volume_id = 1; 1026 | 1027 | // Secrets required by plugin to complete modify volume request. 1028 | // This field is OPTIONAL. Refer to the `Secrets Requirements` 1029 | // section on how to use this field. 1030 | map secrets = 2 [(csi_secret) = true]; 1031 | 1032 | // Plugin specific volume attributes to mutate, passed in as 1033 | // opaque key-value pairs. 1034 | // This field is REQUIRED. The Plugin is responsible for 1035 | // parsing and validating these parameters. COs will treat these 1036 | // as opaque. The CO SHOULD specify the intended values of all mutable 1037 | // parameters it intends to modify. SPs MUST NOT modify volumes based 1038 | // on the absence of keys, only keys that are specified should result 1039 | // in modifications to the volume. 1040 | map mutable_parameters = 3; 1041 | } 1042 | 1043 | message ControllerModifyVolumeResponse { 1044 | } 1045 | 1046 | message GetCapacityRequest { 1047 | // If specified, the Plugin SHALL report the capacity of the storage 1048 | // that can be used to provision volumes that satisfy ALL of the 1049 | // specified `volume_capabilities`. These are the same 1050 | // `volume_capabilities` the CO will use in `CreateVolumeRequest`. 1051 | // This field is OPTIONAL. 1052 | repeated VolumeCapability volume_capabilities = 1; 1053 | 1054 | // If specified, the Plugin SHALL report the capacity of the storage 1055 | // that can be used to provision volumes with the given Plugin 1056 | // specific `parameters`. These are the same `parameters` the CO will 1057 | // use in `CreateVolumeRequest`. This field is OPTIONAL. 1058 | map parameters = 2; 1059 | 1060 | // If specified, the Plugin SHALL report the capacity of the storage 1061 | // that can be used to provision volumes that in the specified 1062 | // `accessible_topology`. This is the same as the 1063 | // `accessible_topology` the CO returns in a `CreateVolumeResponse`. 1064 | // This field is OPTIONAL. This field SHALL NOT be set unless the 1065 | // plugin advertises the VOLUME_ACCESSIBILITY_CONSTRAINTS capability. 1066 | Topology accessible_topology = 3; 1067 | } 1068 | 1069 | message GetCapacityResponse { 1070 | // The available capacity, in bytes, of the storage that can be used 1071 | // to provision volumes. If `volume_capabilities` or `parameters` is 1072 | // specified in the request, the Plugin SHALL take those into 1073 | // consideration when calculating the available capacity of the 1074 | // storage. This field is REQUIRED. 1075 | // The value of this field MUST NOT be negative. 1076 | int64 available_capacity = 1; 1077 | 1078 | // The largest size that may be used in a 1079 | // CreateVolumeRequest.capacity_range.required_bytes field 1080 | // to create a volume with the same parameters as those in 1081 | // GetCapacityRequest. 1082 | // 1083 | // If `volume_capabilities` or `parameters` is 1084 | // specified in the request, the Plugin SHALL take those into 1085 | // consideration when calculating the minimum volume size of the 1086 | // storage. 1087 | // 1088 | // This field is OPTIONAL. MUST NOT be negative. 1089 | // The Plugin SHOULD provide a value for this field if it has 1090 | // a maximum size for individual volumes and leave it unset 1091 | // otherwise. COs MAY use it to make decision about 1092 | // where to create volumes. 1093 | google.protobuf.Int64Value maximum_volume_size = 2; 1094 | 1095 | // The smallest size that may be used in a 1096 | // CreateVolumeRequest.capacity_range.limit_bytes field 1097 | // to create a volume with the same parameters as those in 1098 | // GetCapacityRequest. 1099 | // 1100 | // If `volume_capabilities` or `parameters` is 1101 | // specified in the request, the Plugin SHALL take those into 1102 | // consideration when calculating the maximum volume size of the 1103 | // storage. 1104 | // 1105 | // This field is OPTIONAL. MUST NOT be negative. 1106 | // The Plugin SHOULD provide a value for this field if it has 1107 | // a minimum size for individual volumes and leave it unset 1108 | // otherwise. COs MAY use it to make decision about 1109 | // where to create volumes. 1110 | google.protobuf.Int64Value minimum_volume_size = 3 1111 | [(alpha_field) = true]; 1112 | } 1113 | message ControllerGetCapabilitiesRequest { 1114 | // Intentionally empty. 1115 | } 1116 | 1117 | message ControllerGetCapabilitiesResponse { 1118 | // All the capabilities that the controller service supports. This 1119 | // field is OPTIONAL. 1120 | repeated ControllerServiceCapability capabilities = 1; 1121 | } 1122 | 1123 | // Specifies a capability of the controller service. 1124 | message ControllerServiceCapability { 1125 | message RPC { 1126 | enum Type { 1127 | UNKNOWN = 0; 1128 | CREATE_DELETE_VOLUME = 1; 1129 | PUBLISH_UNPUBLISH_VOLUME = 2; 1130 | LIST_VOLUMES = 3; 1131 | GET_CAPACITY = 4; 1132 | // Currently the only way to consume a snapshot is to create 1133 | // a volume from it. Therefore plugins supporting 1134 | // CREATE_DELETE_SNAPSHOT MUST support creating volume from 1135 | // snapshot. 1136 | CREATE_DELETE_SNAPSHOT = 5; 1137 | LIST_SNAPSHOTS = 6; 1138 | 1139 | // Plugins supporting volume cloning at the storage level MAY 1140 | // report this capability. The source volume MUST be managed by 1141 | // the same plugin. Not all volume sources and parameters 1142 | // combinations MAY work. 1143 | CLONE_VOLUME = 7; 1144 | 1145 | // Indicates the SP supports ControllerPublishVolume.readonly 1146 | // field. 1147 | PUBLISH_READONLY = 8; 1148 | 1149 | // See VolumeExpansion for details. 1150 | EXPAND_VOLUME = 9; 1151 | 1152 | // Indicates the SP supports the 1153 | // ListVolumesResponse.entry.published_node_ids field and the 1154 | // ControllerGetVolumeResponse.published_node_ids field. 1155 | // The SP MUST also support PUBLISH_UNPUBLISH_VOLUME. 1156 | LIST_VOLUMES_PUBLISHED_NODES = 10; 1157 | 1158 | // Indicates that the Controller service can report volume 1159 | // conditions. 1160 | // An SP MAY implement `VolumeCondition` in only the Controller 1161 | // Plugin, only the Node Plugin, or both. 1162 | // If `VolumeCondition` is implemented in both the Controller and 1163 | // Node Plugins, it SHALL report from different perspectives. 1164 | // If for some reason Controller and Node Plugins report 1165 | // misaligned volume conditions, CO SHALL assume the worst case 1166 | // is the truth. 1167 | // Note that, for alpha, `VolumeCondition` is intended be 1168 | // informative for humans only, not for automation. 1169 | VOLUME_CONDITION = 11 [(alpha_enum_value) = true]; 1170 | 1171 | // Indicates the SP supports the ControllerGetVolume RPC. 1172 | // This enables COs to, for example, fetch per volume 1173 | // condition after a volume is provisioned. 1174 | GET_VOLUME = 12 [(alpha_enum_value) = true]; 1175 | 1176 | // Indicates the SP supports the SINGLE_NODE_SINGLE_WRITER and/or 1177 | // SINGLE_NODE_MULTI_WRITER access modes. 1178 | // These access modes are intended to replace the 1179 | // SINGLE_NODE_WRITER access mode to clarify the number of writers 1180 | // for a volume on a single node. Plugins MUST accept and allow 1181 | // use of the SINGLE_NODE_WRITER access mode when either 1182 | // SINGLE_NODE_SINGLE_WRITER and/or SINGLE_NODE_MULTI_WRITER are 1183 | // supported, in order to permit older COs to continue working. 1184 | SINGLE_NODE_MULTI_WRITER = 13 [(alpha_enum_value) = true]; 1185 | 1186 | // Indicates the SP supports modifying volume with mutable 1187 | // parameters. See ControllerModifyVolume for details. 1188 | MODIFY_VOLUME = 14; 1189 | 1190 | // Indicates the SP supports the GetSnapshot RPC. 1191 | // This enables COs to fetch an existing snapshot. 1192 | GET_SNAPSHOT = 15 [(alpha_enum_value) = true]; 1193 | } 1194 | 1195 | Type type = 1; 1196 | } 1197 | 1198 | oneof type { 1199 | // RPC that the controller supports. 1200 | RPC rpc = 1; 1201 | } 1202 | } 1203 | message CreateSnapshotRequest { 1204 | // The ID of the source volume to be snapshotted. 1205 | // This field is REQUIRED. 1206 | string source_volume_id = 1; 1207 | 1208 | // The suggested name for the snapshot. This field is REQUIRED for 1209 | // idempotency. 1210 | // Any Unicode string that conforms to the length limit is allowed 1211 | // except those containing the following banned characters: 1212 | // U+0000-U+0008, U+000B, U+000C, U+000E-U+001F, U+007F-U+009F. 1213 | // (These are control characters other than commonly used whitespace.) 1214 | string name = 2; 1215 | 1216 | // Secrets required by plugin to complete snapshot creation request. 1217 | // This field is OPTIONAL. Refer to the `Secrets Requirements` 1218 | // section on how to use this field. 1219 | map secrets = 3 [(csi_secret) = true]; 1220 | 1221 | // Plugin specific parameters passed in as opaque key-value pairs. 1222 | // This field is OPTIONAL. The Plugin is responsible for parsing and 1223 | // validating these parameters. COs will treat these as opaque. 1224 | // Use cases for opaque parameters: 1225 | // - Specify a policy to automatically clean up the snapshot. 1226 | // - Specify an expiration date for the snapshot. 1227 | // - Specify whether the snapshot is readonly or read/write. 1228 | // - Specify if the snapshot should be replicated to some place. 1229 | // - Specify primary or secondary for replication systems that 1230 | // support snapshotting only on primary. 1231 | map parameters = 4; 1232 | } 1233 | 1234 | message CreateSnapshotResponse { 1235 | // Contains all attributes of the newly created snapshot that are 1236 | // relevant to the CO along with information required by the Plugin 1237 | // to uniquely identify the snapshot. This field is REQUIRED. 1238 | Snapshot snapshot = 1; 1239 | } 1240 | 1241 | // Information about a specific snapshot. 1242 | message Snapshot { 1243 | // This is the complete size of the snapshot in bytes. The purpose of 1244 | // this field is to give CO guidance on how much space is needed to 1245 | // create a volume from this snapshot. The size of the volume MUST NOT 1246 | // be less than the size of the source snapshot. This field is 1247 | // OPTIONAL. If this field is not set, it indicates that this size is 1248 | // unknown. The value of this field MUST NOT be negative and a size of 1249 | // zero means it is unspecified. 1250 | int64 size_bytes = 1; 1251 | 1252 | // The identifier for this snapshot, generated by the plugin. 1253 | // This field is REQUIRED. 1254 | // This field MUST contain enough information to uniquely identify 1255 | // this specific snapshot vs all other snapshots supported by this 1256 | // plugin. 1257 | // This field SHALL be used by the CO in subsequent calls to refer to 1258 | // this snapshot. 1259 | // The SP is NOT responsible for global uniqueness of snapshot_id 1260 | // across multiple SPs. 1261 | string snapshot_id = 2; 1262 | 1263 | // Identity information for the source volume. Note that creating a 1264 | // snapshot from a snapshot is not supported here so the source has to 1265 | // be a volume. This field is REQUIRED. 1266 | string source_volume_id = 3; 1267 | 1268 | // Timestamp when the point-in-time snapshot is taken on the storage 1269 | // system. This field is REQUIRED. 1270 | .google.protobuf.Timestamp creation_time = 4; 1271 | 1272 | // Indicates if a snapshot is ready to use as a 1273 | // `volume_content_source` in a `CreateVolumeRequest`. The default 1274 | // value is false. This field is REQUIRED. 1275 | bool ready_to_use = 5; 1276 | 1277 | // The ID of the volume group snapshot that this snapshot is part of. 1278 | // It uniquely identifies the group snapshot on the storage system. 1279 | // This field is OPTIONAL. 1280 | // If this snapshot is a member of a volume group snapshot, and it 1281 | // MUST NOT be deleted as a stand alone snapshot, then the SP 1282 | // MUST provide the ID of the volume group snapshot in this field. 1283 | // If provided, CO MUST use this field in subsequent volume group 1284 | // snapshot operations to indicate that this snapshot is part of the 1285 | // specified group snapshot. 1286 | // If not provided, CO SHALL treat the snapshot as independent, 1287 | // and SP SHALL allow it to be deleted separately. 1288 | // If this message is inside a VolumeGroupSnapshot message, the value 1289 | // MUST be the same as the group_snapshot_id in that message. 1290 | string group_snapshot_id = 6; 1291 | } 1292 | message DeleteSnapshotRequest { 1293 | // The ID of the snapshot to be deleted. 1294 | // This field is REQUIRED. 1295 | string snapshot_id = 1; 1296 | 1297 | // Secrets required by plugin to complete snapshot deletion request. 1298 | // This field is OPTIONAL. Refer to the `Secrets Requirements` 1299 | // section on how to use this field. 1300 | map secrets = 2 [(csi_secret) = true]; 1301 | } 1302 | 1303 | message DeleteSnapshotResponse {} 1304 | // List all snapshots on the storage system regardless of how they were 1305 | // created. 1306 | message ListSnapshotsRequest { 1307 | // If specified (non-zero value), the Plugin MUST NOT return more 1308 | // entries than this number in the response. If the actual number of 1309 | // entries is more than this number, the Plugin MUST set `next_token` 1310 | // in the response which can be used to get the next page of entries 1311 | // in the subsequent `ListSnapshots` call. This field is OPTIONAL. If 1312 | // not specified (zero value), it means there is no restriction on the 1313 | // number of entries that can be returned. 1314 | // The value of this field MUST NOT be negative. 1315 | int32 max_entries = 1; 1316 | 1317 | // A token to specify where to start paginating. Set this field to 1318 | // `next_token` returned by a previous `ListSnapshots` call to get the 1319 | // next page of entries. This field is OPTIONAL. 1320 | // An empty string is equal to an unspecified field value. 1321 | string starting_token = 2; 1322 | 1323 | // Identity information for the source volume. This field is OPTIONAL. 1324 | // It can be used to list snapshots by volume. 1325 | string source_volume_id = 3; 1326 | 1327 | // Identity information for a specific snapshot. This field is 1328 | // OPTIONAL. It can be used to list only a specific snapshot. 1329 | // ListSnapshots will return with current snapshot information 1330 | // and will not block if the snapshot is being processed after 1331 | // it is cut. 1332 | string snapshot_id = 4; 1333 | 1334 | // Secrets required by plugin to complete ListSnapshot request. 1335 | // This field is OPTIONAL. Refer to the `Secrets Requirements` 1336 | // section on how to use this field. 1337 | map secrets = 5 [(csi_secret) = true]; 1338 | } 1339 | 1340 | message ListSnapshotsResponse { 1341 | message Entry { 1342 | Snapshot snapshot = 1; 1343 | } 1344 | 1345 | repeated Entry entries = 1; 1346 | 1347 | // This token allows you to get the next page of entries for 1348 | // `ListSnapshots` request. If the number of entries is larger than 1349 | // `max_entries`, use the `next_token` as a value for the 1350 | // `starting_token` field in the next `ListSnapshots` request. This 1351 | // field is OPTIONAL. 1352 | // An empty string is equal to an unspecified field value. 1353 | string next_token = 2; 1354 | } 1355 | message GetSnapshotRequest { 1356 | option (alpha_message) = true; 1357 | 1358 | // The ID of the snapshot to fetch current snapshot information for. 1359 | // This field is REQUIRED. 1360 | string snapshot_id = 1; 1361 | 1362 | // Secrets required by plugin to complete GetSnapshot request. 1363 | // This field is OPTIONAL. Refer to the `Secrets Requirements` 1364 | // section on how to use this field. 1365 | map secrets = 2 [(csi_secret) = true]; 1366 | } 1367 | 1368 | message GetSnapshotResponse { 1369 | option (alpha_message) = true; 1370 | 1371 | // This field is REQUIRED 1372 | Snapshot snapshot = 1; 1373 | } 1374 | message ControllerExpandVolumeRequest { 1375 | // The ID of the volume to expand. This field is REQUIRED. 1376 | string volume_id = 1; 1377 | 1378 | // This allows CO to specify the capacity requirements of the volume 1379 | // after expansion. This field is REQUIRED. 1380 | CapacityRange capacity_range = 2; 1381 | 1382 | // Secrets required by the plugin for expanding the volume. 1383 | // This field is OPTIONAL. 1384 | map secrets = 3 [(csi_secret) = true]; 1385 | 1386 | // Volume capability describing how the CO intends to use this volume. 1387 | // This allows SP to determine if volume is being used as a block 1388 | // device or mounted file system. For example - if volume is 1389 | // being used as a block device - the SP MAY set 1390 | // node_expansion_required to false in ControllerExpandVolumeResponse 1391 | // to skip invocation of NodeExpandVolume on the node by the CO. 1392 | // This is an OPTIONAL field. 1393 | VolumeCapability volume_capability = 4; 1394 | } 1395 | 1396 | message ControllerExpandVolumeResponse { 1397 | // Capacity of volume after expansion. This field is REQUIRED. 1398 | int64 capacity_bytes = 1; 1399 | 1400 | // Whether node expansion is required for the volume. When true 1401 | // the CO MUST make NodeExpandVolume RPC call on the node. This field 1402 | // is REQUIRED. 1403 | bool node_expansion_required = 2; 1404 | } 1405 | message NodeStageVolumeRequest { 1406 | // The ID of the volume to publish. This field is REQUIRED. 1407 | string volume_id = 1; 1408 | 1409 | // The CO SHALL set this field to the value returned by 1410 | // `ControllerPublishVolume` if the corresponding Controller Plugin 1411 | // has `PUBLISH_UNPUBLISH_VOLUME` controller capability, and SHALL be 1412 | // left unset if the corresponding Controller Plugin does not have 1413 | // this capability. This is an OPTIONAL field. 1414 | map publish_context = 2; 1415 | 1416 | // The path to which the volume MAY be staged. It MUST be an 1417 | // absolute path in the root filesystem of the process serving this 1418 | // request, and MUST be a directory. The CO SHALL ensure that there 1419 | // is only one `staging_target_path` per volume. The CO SHALL ensure 1420 | // that the path is directory and that the process serving the 1421 | // request has `read` and `write` permission to that directory. The 1422 | // CO SHALL be responsible for creating the directory if it does not 1423 | // exist. 1424 | // This is a REQUIRED field. 1425 | // This field overrides the general CSI size limit. 1426 | // SP SHOULD support the maximum path length allowed by the operating 1427 | // system/filesystem, but, at a minimum, SP MUST accept a max path 1428 | // length of at least 128 bytes. 1429 | string staging_target_path = 3; 1430 | 1431 | // Volume capability describing how the CO intends to use this volume. 1432 | // SP MUST ensure the CO can use the staged volume as described. 1433 | // Otherwise SP MUST return the appropriate gRPC error code. 1434 | // This is a REQUIRED field. 1435 | VolumeCapability volume_capability = 4; 1436 | 1437 | // Secrets required by plugin to complete node stage volume request. 1438 | // This field is OPTIONAL. Refer to the `Secrets Requirements` 1439 | // section on how to use this field. 1440 | map secrets = 5 [(csi_secret) = true]; 1441 | 1442 | // Volume context as returned by SP in 1443 | // CreateVolumeResponse.Volume.volume_context. 1444 | // This field is OPTIONAL and MUST match the volume_context of the 1445 | // volume identified by `volume_id`. 1446 | map volume_context = 6; 1447 | } 1448 | 1449 | message NodeStageVolumeResponse { 1450 | // Intentionally empty. 1451 | } 1452 | message NodeUnstageVolumeRequest { 1453 | // The ID of the volume. This field is REQUIRED. 1454 | string volume_id = 1; 1455 | 1456 | // The path at which the volume was staged. It MUST be an absolute 1457 | // path in the root filesystem of the process serving this request. 1458 | // This is a REQUIRED field. 1459 | // This field overrides the general CSI size limit. 1460 | // SP SHOULD support the maximum path length allowed by the operating 1461 | // system/filesystem, but, at a minimum, SP MUST accept a max path 1462 | // length of at least 128 bytes. 1463 | string staging_target_path = 2; 1464 | } 1465 | 1466 | message NodeUnstageVolumeResponse { 1467 | // Intentionally empty. 1468 | } 1469 | message NodePublishVolumeRequest { 1470 | // The ID of the volume to publish. This field is REQUIRED. 1471 | string volume_id = 1; 1472 | 1473 | // The CO SHALL set this field to the value returned by 1474 | // `ControllerPublishVolume` if the corresponding Controller Plugin 1475 | // has `PUBLISH_UNPUBLISH_VOLUME` controller capability, and SHALL be 1476 | // left unset if the corresponding Controller Plugin does not have 1477 | // this capability. This is an OPTIONAL field. 1478 | map publish_context = 2; 1479 | 1480 | // The path to which the volume was staged by `NodeStageVolume`. 1481 | // It MUST be an absolute path in the root filesystem of the process 1482 | // serving this request. 1483 | // It MUST be set if the Node Plugin implements the 1484 | // `STAGE_UNSTAGE_VOLUME` node capability. 1485 | // This is an OPTIONAL field. 1486 | // This field overrides the general CSI size limit. 1487 | // SP SHOULD support the maximum path length allowed by the operating 1488 | // system/filesystem, but, at a minimum, SP MUST accept a max path 1489 | // length of at least 128 bytes. 1490 | string staging_target_path = 3; 1491 | 1492 | // The path to which the volume will be published. It MUST be an 1493 | // absolute path in the root filesystem of the process serving this 1494 | // request. The CO SHALL ensure uniqueness of target_path per volume. 1495 | // The CO SHALL ensure that the parent directory of this path exists 1496 | // and that the process serving the request has `read` and `write` 1497 | // permissions to that parent directory. 1498 | // For volumes with an access type of block, the SP SHALL place the 1499 | // block device at target_path. 1500 | // For volumes with an access type of mount, the SP SHALL place the 1501 | // mounted directory at target_path. 1502 | // Creation of target_path is the responsibility of the SP. 1503 | // This is a REQUIRED field. 1504 | // This field overrides the general CSI size limit. 1505 | // SP SHOULD support the maximum path length allowed by the operating 1506 | // system/filesystem, but, at a minimum, SP MUST accept a max path 1507 | // length of at least 128 bytes. 1508 | string target_path = 4; 1509 | 1510 | // Volume capability describing how the CO intends to use this volume. 1511 | // SP MUST ensure the CO can use the published volume as described. 1512 | // Otherwise SP MUST return the appropriate gRPC error code. 1513 | // This is a REQUIRED field. 1514 | VolumeCapability volume_capability = 5; 1515 | 1516 | // Indicates SP MUST publish the volume in readonly mode. 1517 | // This field is REQUIRED. 1518 | bool readonly = 6; 1519 | 1520 | // Secrets required by plugin to complete node publish volume request. 1521 | // This field is OPTIONAL. Refer to the `Secrets Requirements` 1522 | // section on how to use this field. 1523 | map secrets = 7 [(csi_secret) = true]; 1524 | 1525 | // Volume context as returned by SP in 1526 | // CreateVolumeResponse.Volume.volume_context. 1527 | // This field is OPTIONAL and MUST match the volume_context of the 1528 | // volume identified by `volume_id`. 1529 | map volume_context = 8; 1530 | } 1531 | 1532 | message NodePublishVolumeResponse { 1533 | // Intentionally empty. 1534 | } 1535 | message NodeUnpublishVolumeRequest { 1536 | // The ID of the volume. This field is REQUIRED. 1537 | string volume_id = 1; 1538 | 1539 | // The path at which the volume was published. It MUST be an absolute 1540 | // path in the root filesystem of the process serving this request. 1541 | // The SP MUST delete the file or directory it created at this path. 1542 | // This is a REQUIRED field. 1543 | // This field overrides the general CSI size limit. 1544 | // SP SHOULD support the maximum path length allowed by the operating 1545 | // system/filesystem, but, at a minimum, SP MUST accept a max path 1546 | // length of at least 128 bytes. 1547 | string target_path = 2; 1548 | } 1549 | 1550 | message NodeUnpublishVolumeResponse { 1551 | // Intentionally empty. 1552 | } 1553 | message NodeGetVolumeStatsRequest { 1554 | // The ID of the volume. This field is REQUIRED. 1555 | string volume_id = 1; 1556 | 1557 | // It can be any valid path where volume was previously 1558 | // staged or published. 1559 | // It MUST be an absolute path in the root filesystem of 1560 | // the process serving this request. 1561 | // This is a REQUIRED field. 1562 | // This field overrides the general CSI size limit. 1563 | // SP SHOULD support the maximum path length allowed by the operating 1564 | // system/filesystem, but, at a minimum, SP MUST accept a max path 1565 | // length of at least 128 bytes. 1566 | string volume_path = 2; 1567 | 1568 | // The path where the volume is staged, if the plugin has the 1569 | // STAGE_UNSTAGE_VOLUME capability, otherwise empty. 1570 | // If not empty, it MUST be an absolute path in the root 1571 | // filesystem of the process serving this request. 1572 | // This field is OPTIONAL. 1573 | // This field overrides the general CSI size limit. 1574 | // SP SHOULD support the maximum path length allowed by the operating 1575 | // system/filesystem, but, at a minimum, SP MUST accept a max path 1576 | // length of at least 128 bytes. 1577 | string staging_target_path = 3; 1578 | } 1579 | 1580 | message NodeGetVolumeStatsResponse { 1581 | // This field is OPTIONAL. 1582 | repeated VolumeUsage usage = 1; 1583 | // Information about the current condition of the volume. 1584 | // This field is OPTIONAL. 1585 | // This field MUST be specified if the VOLUME_CONDITION node 1586 | // capability is supported. 1587 | VolumeCondition volume_condition = 2 [(alpha_field) = true]; 1588 | } 1589 | 1590 | message VolumeUsage { 1591 | enum Unit { 1592 | UNKNOWN = 0; 1593 | BYTES = 1; 1594 | INODES = 2; 1595 | } 1596 | // The available capacity in specified Unit. This field is OPTIONAL. 1597 | // The value of this field MUST NOT be negative. 1598 | int64 available = 1; 1599 | 1600 | // The total capacity in specified Unit. This field is REQUIRED. 1601 | // The value of this field MUST NOT be negative. 1602 | int64 total = 2; 1603 | 1604 | // The used capacity in specified Unit. This field is OPTIONAL. 1605 | // The value of this field MUST NOT be negative. 1606 | int64 used = 3; 1607 | 1608 | // Units by which values are measured. This field is REQUIRED. 1609 | Unit unit = 4; 1610 | } 1611 | 1612 | // VolumeCondition represents the current condition of a volume. 1613 | message VolumeCondition { 1614 | option (alpha_message) = true; 1615 | 1616 | // Normal volumes are available for use and operating optimally. 1617 | // An abnormal volume does not meet these criteria. 1618 | // This field is REQUIRED. 1619 | bool abnormal = 1; 1620 | 1621 | // The message describing the condition of the volume. 1622 | // This field is REQUIRED. 1623 | string message = 2; 1624 | } 1625 | message NodeGetCapabilitiesRequest { 1626 | // Intentionally empty. 1627 | } 1628 | 1629 | message NodeGetCapabilitiesResponse { 1630 | // All the capabilities that the node service supports. This field 1631 | // is OPTIONAL. 1632 | repeated NodeServiceCapability capabilities = 1; 1633 | } 1634 | 1635 | // Specifies a capability of the node service. 1636 | message NodeServiceCapability { 1637 | message RPC { 1638 | enum Type { 1639 | UNKNOWN = 0; 1640 | STAGE_UNSTAGE_VOLUME = 1; 1641 | // If Plugin implements GET_VOLUME_STATS capability 1642 | // then it MUST implement NodeGetVolumeStats RPC 1643 | // call for fetching volume statistics. 1644 | GET_VOLUME_STATS = 2; 1645 | // See VolumeExpansion for details. 1646 | EXPAND_VOLUME = 3; 1647 | // Indicates that the Node service can report volume conditions. 1648 | // An SP MAY implement `VolumeCondition` in only the Node 1649 | // Plugin, only the Controller Plugin, or both. 1650 | // If `VolumeCondition` is implemented in both the Node and 1651 | // Controller Plugins, it SHALL report from different 1652 | // perspectives. 1653 | // If for some reason Node and Controller Plugins report 1654 | // misaligned volume conditions, CO SHALL assume the worst case 1655 | // is the truth. 1656 | // Note that, for alpha, `VolumeCondition` is intended to be 1657 | // informative for humans only, not for automation. 1658 | VOLUME_CONDITION = 4 [(alpha_enum_value) = true]; 1659 | 1660 | // Indicates the SP supports the SINGLE_NODE_SINGLE_WRITER and/or 1661 | // SINGLE_NODE_MULTI_WRITER access modes. 1662 | // These access modes are intended to replace the 1663 | // SINGLE_NODE_WRITER access mode to clarify the number of writers 1664 | // for a volume on a single node. Plugins MUST accept and allow 1665 | // use of the SINGLE_NODE_WRITER access mode (subject to the 1666 | // processing rules for NodePublishVolume), when either 1667 | // SINGLE_NODE_SINGLE_WRITER and/or SINGLE_NODE_MULTI_WRITER are 1668 | // supported, in order to permit older COs to continue working. 1669 | SINGLE_NODE_MULTI_WRITER = 5 [(alpha_enum_value) = true]; 1670 | 1671 | // Indicates that Node service supports mounting volumes 1672 | // with provided volume group identifier during node stage 1673 | // or node publish RPC calls. 1674 | VOLUME_MOUNT_GROUP = 6; 1675 | } 1676 | 1677 | Type type = 1; 1678 | } 1679 | 1680 | oneof type { 1681 | // RPC that the controller supports. 1682 | RPC rpc = 1; 1683 | } 1684 | } 1685 | message NodeGetInfoRequest { 1686 | } 1687 | 1688 | message NodeGetInfoResponse { 1689 | // The identifier of the node as understood by the SP. 1690 | // This field is REQUIRED. 1691 | // This field MUST contain enough information to uniquely identify 1692 | // this specific node vs all other nodes supported by this plugin. 1693 | // This field SHALL be used by the CO in subsequent calls, including 1694 | // `ControllerPublishVolume`, to refer to this node. 1695 | // The SP is NOT responsible for global uniqueness of node_id across 1696 | // multiple SPs. 1697 | // This field overrides the general CSI size limit. 1698 | // The size of this field SHALL NOT exceed 256 bytes. The general 1699 | // CSI size limit, 128 byte, is RECOMMENDED for best backwards 1700 | // compatibility. 1701 | string node_id = 1; 1702 | 1703 | // Maximum number of volumes that controller can publish to the node. 1704 | // If value is not set or zero CO SHALL decide how many volumes of 1705 | // this type can be published by the controller to the node. The 1706 | // plugin MUST NOT set negative values here. 1707 | // This field is OPTIONAL. 1708 | int64 max_volumes_per_node = 2; 1709 | 1710 | // Specifies where (regions, zones, racks, etc.) the node is 1711 | // accessible from. 1712 | // A plugin that returns this field MUST also set the 1713 | // VOLUME_ACCESSIBILITY_CONSTRAINTS plugin capability. 1714 | // COs MAY use this information along with the topology information 1715 | // returned in CreateVolumeResponse to ensure that a given volume is 1716 | // accessible from a given node when scheduling workloads. 1717 | // This field is OPTIONAL. If it is not specified, the CO MAY assume 1718 | // the node is not subject to any topological constraint, and MAY 1719 | // schedule workloads that reference any volume V, such that there are 1720 | // no topological constraints declared for V. 1721 | // 1722 | // Example 1: 1723 | // accessible_topology = 1724 | // {"region": "R1", "zone": "Z2"} 1725 | // Indicates the node exists within the "region" "R1" and the "zone" 1726 | // "Z2". 1727 | Topology accessible_topology = 3; 1728 | } 1729 | message NodeExpandVolumeRequest { 1730 | // The ID of the volume. This field is REQUIRED. 1731 | string volume_id = 1; 1732 | 1733 | // The path on which volume is available. This field is REQUIRED. 1734 | // This field overrides the general CSI size limit. 1735 | // SP SHOULD support the maximum path length allowed by the operating 1736 | // system/filesystem, but, at a minimum, SP MUST accept a max path 1737 | // length of at least 128 bytes. 1738 | string volume_path = 2; 1739 | 1740 | // This allows CO to specify the capacity requirements of the volume 1741 | // after expansion. If capacity_range is omitted then a plugin MAY 1742 | // inspect the file system of the volume to determine the maximum 1743 | // capacity to which the volume can be expanded. In such cases a 1744 | // plugin MAY expand the volume to its maximum capacity. 1745 | // This field is OPTIONAL. 1746 | CapacityRange capacity_range = 3; 1747 | 1748 | // The path where the volume is staged, if the plugin has the 1749 | // STAGE_UNSTAGE_VOLUME capability, otherwise empty. 1750 | // If not empty, it MUST be an absolute path in the root 1751 | // filesystem of the process serving this request. 1752 | // This field is OPTIONAL. 1753 | // This field overrides the general CSI size limit. 1754 | // SP SHOULD support the maximum path length allowed by the operating 1755 | // system/filesystem, but, at a minimum, SP MUST accept a max path 1756 | // length of at least 128 bytes. 1757 | string staging_target_path = 4; 1758 | 1759 | // Volume capability describing how the CO intends to use this volume. 1760 | // This allows SP to determine if volume is being used as a block 1761 | // device or mounted file system. For example - if volume is being 1762 | // used as a block device the SP MAY choose to skip expanding the 1763 | // filesystem in NodeExpandVolume implementation but still perform 1764 | // rest of the housekeeping needed for expanding the volume. If 1765 | // volume_capability is omitted the SP MAY determine 1766 | // access_type from given volume_path for the volume and perform 1767 | // node expansion. This is an OPTIONAL field. 1768 | VolumeCapability volume_capability = 5; 1769 | 1770 | // Secrets required by plugin to complete node expand volume request. 1771 | // This field is OPTIONAL. Refer to the `Secrets Requirements` 1772 | // section on how to use this field. 1773 | map secrets = 6 1774 | [(csi_secret) = true, (alpha_field) = true]; 1775 | } 1776 | 1777 | message NodeExpandVolumeResponse { 1778 | // The capacity of the volume in bytes. This field is OPTIONAL. 1779 | int64 capacity_bytes = 1; 1780 | } 1781 | message GroupControllerGetCapabilitiesRequest { 1782 | // Intentionally empty. 1783 | } 1784 | 1785 | message GroupControllerGetCapabilitiesResponse { 1786 | // All the capabilities that the group controller service supports. 1787 | // This field is OPTIONAL. 1788 | repeated GroupControllerServiceCapability capabilities = 1; 1789 | } 1790 | 1791 | // Specifies a capability of the group controller service. 1792 | message GroupControllerServiceCapability { 1793 | message RPC { 1794 | enum Type { 1795 | UNKNOWN = 0; 1796 | 1797 | // Indicates that the group controller plugin supports 1798 | // creating, deleting, and getting details of a volume 1799 | // group snapshot. 1800 | CREATE_DELETE_GET_VOLUME_GROUP_SNAPSHOT = 1; 1801 | } 1802 | 1803 | Type type = 1; 1804 | } 1805 | 1806 | oneof type { 1807 | // RPC that the controller supports. 1808 | RPC rpc = 1; 1809 | } 1810 | } 1811 | message CreateVolumeGroupSnapshotRequest { 1812 | // The suggested name for the group snapshot. This field is REQUIRED 1813 | // for idempotency. 1814 | // Any Unicode string that conforms to the length limit is allowed 1815 | // except those containing the following banned characters: 1816 | // U+0000-U+0008, U+000B, U+000C, U+000E-U+001F, U+007F-U+009F. 1817 | // (These are control characters other than commonly used whitespace.) 1818 | string name = 1; 1819 | 1820 | // volume IDs of the source volumes to be snapshotted together. 1821 | // This field is REQUIRED. 1822 | repeated string source_volume_ids = 2; 1823 | 1824 | // Secrets required by plugin to complete 1825 | // ControllerCreateVolumeGroupSnapshot request. 1826 | // This field is OPTIONAL. Refer to the `Secrets Requirements` 1827 | // section on how to use this field. 1828 | // The secrets provided in this field SHOULD be the same for 1829 | // all group snapshot operations on the same group snapshot. 1830 | map secrets = 3 [(csi_secret) = true]; 1831 | 1832 | // Plugin specific parameters passed in as opaque key-value pairs. 1833 | // This field is OPTIONAL. The Plugin is responsible for parsing and 1834 | // validating these parameters. COs will treat these as opaque. 1835 | map parameters = 4; 1836 | } 1837 | 1838 | message CreateVolumeGroupSnapshotResponse { 1839 | // Contains all attributes of the newly created group snapshot. 1840 | // This field is REQUIRED. 1841 | VolumeGroupSnapshot group_snapshot = 1; 1842 | } 1843 | 1844 | message VolumeGroupSnapshot { 1845 | // The identifier for this group snapshot, generated by the plugin. 1846 | // This field MUST contain enough information to uniquely identify 1847 | // this specific snapshot vs all other group snapshots supported by 1848 | // this plugin. 1849 | // This field SHALL be used by the CO in subsequent calls to refer to 1850 | // this group snapshot. 1851 | // The SP is NOT responsible for global uniqueness of 1852 | // group_snapshot_id across multiple SPs. 1853 | // This field is REQUIRED. 1854 | string group_snapshot_id = 1; 1855 | 1856 | // A list of snapshots belonging to this group. 1857 | // This field is REQUIRED. 1858 | repeated Snapshot snapshots = 2; 1859 | 1860 | // Timestamp of when the volume group snapshot was taken. 1861 | // This field is REQUIRED. 1862 | .google.protobuf.Timestamp creation_time = 3; 1863 | 1864 | // Indicates if all individual snapshots in the group snapshot 1865 | // are ready to use as a `volume_content_source` in a 1866 | // `CreateVolumeRequest`. The default value is false. 1867 | // If any snapshot in the list of snapshots in this message have 1868 | // ready_to_use set to false, the SP MUST set this field to false. 1869 | // If all of the snapshots in the list of snapshots in this message 1870 | // have ready_to_use set to true, the SP SHOULD set this field to 1871 | // true. 1872 | // This field is REQUIRED. 1873 | bool ready_to_use = 4; 1874 | } 1875 | message DeleteVolumeGroupSnapshotRequest { 1876 | // The ID of the group snapshot to be deleted. 1877 | // This field is REQUIRED. 1878 | string group_snapshot_id = 1; 1879 | 1880 | // A list of snapshot IDs that are part of this group snapshot. 1881 | // If SP does not need to rely on this field to delete the snapshots 1882 | // in the group, it SHOULD check this field and report an error 1883 | // if it has the ability to detect a mismatch. 1884 | // Some SPs require this list to delete the snapshots in the group. 1885 | // If SP needs to use this field to delete the snapshots in the 1886 | // group, it MUST report an error if it has the ability to detect 1887 | // a mismatch. 1888 | // This field is REQUIRED. 1889 | repeated string snapshot_ids = 2; 1890 | 1891 | // Secrets required by plugin to complete group snapshot deletion 1892 | // request. 1893 | // This field is OPTIONAL. Refer to the `Secrets Requirements` 1894 | // section on how to use this field. 1895 | // The secrets provided in this field SHOULD be the same for 1896 | // all group snapshot operations on the same group snapshot. 1897 | map secrets = 3 [(csi_secret) = true]; 1898 | } 1899 | 1900 | message DeleteVolumeGroupSnapshotResponse { 1901 | // Intentionally empty. 1902 | } 1903 | message GetVolumeGroupSnapshotRequest { 1904 | // The ID of the group snapshot to fetch current group snapshot 1905 | // information for. 1906 | // This field is REQUIRED. 1907 | string group_snapshot_id = 1; 1908 | 1909 | // A list of snapshot IDs that are part of this group snapshot. 1910 | // If SP does not need to rely on this field to get the snapshots 1911 | // in the group, it SHOULD check this field and report an error 1912 | // if it has the ability to detect a mismatch. 1913 | // Some SPs require this list to get the snapshots in the group. 1914 | // If SP needs to use this field to get the snapshots in the 1915 | // group, it MUST report an error if it has the ability to detect 1916 | // a mismatch. 1917 | // This field is REQUIRED. 1918 | repeated string snapshot_ids = 2; 1919 | 1920 | // Secrets required by plugin to complete 1921 | // GetVolumeGroupSnapshot request. 1922 | // This field is OPTIONAL. Refer to the `Secrets Requirements` 1923 | // section on how to use this field. 1924 | // The secrets provided in this field SHOULD be the same for 1925 | // all group snapshot operations on the same group snapshot. 1926 | map secrets = 3 [(csi_secret) = true]; 1927 | } 1928 | 1929 | message GetVolumeGroupSnapshotResponse { 1930 | // This field is REQUIRED 1931 | VolumeGroupSnapshot group_snapshot = 1; 1932 | } 1933 | // BlockMetadata specifies a data range. 1934 | message BlockMetadata { 1935 | // This is the zero based byte position in the volume or snapshot, 1936 | // measured from the start of the object. 1937 | // This field is REQUIRED. 1938 | int64 byte_offset = 1; 1939 | 1940 | // This is the size of the data range. 1941 | // size_bytes MUST be greater than zero. 1942 | // This field is REQUIRED. 1943 | int64 size_bytes = 2; 1944 | } 1945 | enum BlockMetadataType { 1946 | UNKNOWN = 0; 1947 | 1948 | // The FIXED_LENGTH value indicates that data ranges are 1949 | // returned in fixed size blocks. 1950 | FIXED_LENGTH = 1; 1951 | 1952 | // The VARIABLE_LENGTH value indicates that data ranges 1953 | // are returned in potentially variable sized extents. 1954 | VARIABLE_LENGTH = 2; 1955 | } 1956 | // The GetMetadataAllocatedRequest message is used to solicit metadata 1957 | // on the allocated blocks of a snapshot: i.e. this identifies the 1958 | // data ranges that have valid data as they were the target of some 1959 | // previous write operation on the volume. 1960 | message GetMetadataAllocatedRequest { 1961 | // This is the identifier of the snapshot. 1962 | // This field is REQUIRED. 1963 | string snapshot_id = 1; 1964 | 1965 | // This indicates the zero based starting byte position in the volume 1966 | // snapshot from which the result should be computed. 1967 | // It is intended to be used to continue a previously interrupted 1968 | // call. 1969 | // The CO SHOULD specify this value to be the offset of the byte 1970 | // position immediately after the last byte of the last data range 1971 | // received, if continuing an interrupted operation, or zero if not. 1972 | // The SP MUST ensure that the returned response stream does not 1973 | // contain BlockMetadata tuples that end before the requested 1974 | // starting_offset: i.e. if S is the requested starting_offset, and 1975 | // B0 is block_metadata[0] of the first message in the response 1976 | // stream, then (S < B0.byte_offset + B0.size_bytes) must be true. 1977 | // This field is REQUIRED. 1978 | int64 starting_offset = 2; 1979 | 1980 | // This is an optional parameter, and if non-zero it specifies the 1981 | // maximum number of tuples to be returned in each 1982 | // GetMetadataAllocatedResponse message returned by the RPC stream. 1983 | // The plugin will determine an appropriate value if 0, and is 1984 | // always free to send less than the requested value. 1985 | // This field is OPTIONAL. 1986 | int32 max_results = 3; 1987 | 1988 | // Secrets required by plugin to complete the request. 1989 | // This field is OPTIONAL. Refer to the `Secrets Requirements` 1990 | // section on how to use this field. 1991 | map secrets = 4 [(csi_secret) = true]; 1992 | } 1993 | 1994 | // GetMetadataAllocatedResponse messages are returned in a gRPC stream. 1995 | // Cumulatively, they provide information on the allocated data 1996 | // ranges in the snapshot. 1997 | message GetMetadataAllocatedResponse { 1998 | // This specifies the style used in the BlockMetadata sequence. 1999 | // This value must be the same in all such messages returned by 2000 | // the stream. 2001 | // If block_metadata_type is FIXED_LENGTH, then the size_bytes field 2002 | // of each message in the block_metadata list MUST be constant. 2003 | // This field is REQUIRED. 2004 | BlockMetadataType block_metadata_type = 1; 2005 | 2006 | // This returns the capacity of the underlying volume in bytes. 2007 | // This value must be the same in all such messages returned by 2008 | // the stream. 2009 | // This field is REQUIRED. 2010 | int64 volume_capacity_bytes = 2; 2011 | 2012 | // This is a list of data range tuples. 2013 | // If the value of max_results in the GetMetadataAllocatedRequest 2014 | // message is greater than zero, then the number of entries in this 2015 | // list MUST be less than or equal to that value. 2016 | // The SP MUST respect the value of starting_offset in the request. 2017 | // The byte_offset fields of adjacent BlockMetadata messages 2018 | // MUST be strictly increasing and messages MUST NOT overlap: 2019 | // i.e. for any two BlockMetadata messages, A and B, if A is returned 2020 | // before B, then (A.byte_offset + A.size_bytes <= B.byte_offset) 2021 | // MUST be true. 2022 | // This MUST also be true if A and B are from block_metadata lists in 2023 | // different GetMetadataAllocatedResponse messages in the gRPC stream. 2024 | // This field is OPTIONAL. 2025 | repeated BlockMetadata block_metadata = 3; 2026 | } 2027 | // The GetMetadataDeltaRequest message is used to solicit metadata on 2028 | // the data ranges that have changed between two snapshots. 2029 | message GetMetadataDeltaRequest { 2030 | // This is the identifier of the snapshot against which changes 2031 | // are to be computed. 2032 | // This field is REQUIRED. 2033 | string base_snapshot_id = 1; 2034 | 2035 | // This is the identifier of a second snapshot in the same volume, 2036 | // created after the base snapshot. 2037 | // This field is REQUIRED. 2038 | string target_snapshot_id = 2; 2039 | 2040 | // This indicates the zero based starting byte position in the volume 2041 | // snapshot from which the result should be computed. 2042 | // It is intended to be used to continue a previously interrupted 2043 | // call. 2044 | // The CO SHOULD specify this value to be the offset of the byte 2045 | // position immediately after the last byte of the last data range 2046 | // received, if continuing an interrupted operation, or zero if not. 2047 | // The SP MUST ensure that the returned response stream does not 2048 | // contain BlockMetadata tuples that end before the requested 2049 | // starting_offset: i.e. if S is the requested starting_offset, and 2050 | // B0 is block_metadata[0] of the first message in the response 2051 | // stream, then (S < B0.byte_offset + B0.size_bytes) must be true. 2052 | // This field is REQUIRED. 2053 | int64 starting_offset = 3; 2054 | 2055 | // This is an optional parameter, and if non-zero it specifies the 2056 | // maximum number of tuples to be returned in each 2057 | // GetMetadataDeltaResponse message returned by the RPC stream. 2058 | // The plugin will determine an appropriate value if 0, and is 2059 | // always free to send less than the requested value. 2060 | // This field is OPTIONAL. 2061 | int32 max_results = 4; 2062 | 2063 | // Secrets required by plugin to complete the request. 2064 | // This field is OPTIONAL. Refer to the `Secrets Requirements` 2065 | // section on how to use this field. 2066 | map secrets = 5 [(csi_secret) = true]; 2067 | } 2068 | 2069 | // GetMetadataDeltaResponse messages are returned in a gRPC stream. 2070 | // Cumulatively, they provide information on the data ranges that 2071 | // have changed between the base and target snapshots specified 2072 | // in the GetMetadataDeltaRequest message. 2073 | message GetMetadataDeltaResponse { 2074 | // This specifies the style used in the BlockMetadata sequence. 2075 | // This value must be the same in all such messages returned by 2076 | // the stream. 2077 | // If block_metadata_type is FIXED_LENGTH, then the size_bytes field 2078 | // of each message in the block_metadata list MUST be constant. 2079 | // This field is REQUIRED. 2080 | BlockMetadataType block_metadata_type = 1; 2081 | 2082 | // This returns the capacity of the underlying volume in bytes. 2083 | // This value must be the same in all such messages returned by 2084 | // the stream. 2085 | // This field is REQUIRED. 2086 | int64 volume_capacity_bytes = 2; 2087 | 2088 | // This is a list of data range tuples. 2089 | // If the value of max_results in the GetMetadataDeltaRequest message 2090 | // is greater than zero, then the number of entries in this list MUST 2091 | // be less than or equal to that value. 2092 | // The SP MUST respect the value of starting_offset in the request. 2093 | // The byte_offset fields of adjacent BlockMetadata messages 2094 | // MUST be strictly increasing and messages MUST NOT overlap: 2095 | // i.e. for any two BlockMetadata messages, A and B, if A is returned 2096 | // before B, then (A.byte_offset + A.size_bytes <= B.byte_offset) 2097 | // MUST be true. 2098 | // This MUST also be true if A and B are from block_metadata lists in 2099 | // different GetMetadataDeltaResponse messages in the gRPC stream. 2100 | // This field is OPTIONAL. 2101 | repeated BlockMetadata block_metadata = 3; 2102 | } 2103 | --------------------------------------------------------------------------------