Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# some arguments that must be supplied
ARG GOIMAGE
ARG BASEIMAGE
ARG VERSION="2.16.0"
ARG VERSION="2.17.0"

# Stage to build the driver
FROM $GOIMAGE as builder
Expand All @@ -35,7 +35,7 @@ LABEL vendor="Dell Technologies" \
name="csi-powerstore" \
summary="CSI Driver for Dell EMC PowerStore" \
description="CSI Driver for provisioning persistent storage from Dell EMC PowerStore" \
release="1.16.0" \
release="1.17.0" \
version=$VERSION \
license="Apache-2.0"
COPY licenses /licenses
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ coverage:
cd ./pkg; go tool cover -html=coverage.out -o coverage.html

go-code-tester:
git clone --depth 1 git@github.com:CSM/actions.git temp-repo
git clone --depth 1 git@github.com:dell/actions.git temp-repo
cp temp-repo/go-code-tester/entrypoint.sh ./go-code-tester
chmod +x go-code-tester
rm -rf temp-repo
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,12 @@ If you want to use NVMe/FC be sure that the NVMeFC zoning of the Host Bus Adapte
## Documentation
For more detailed information on the driver, please refer to [Container Storage Modules documentation](https://dell.github.io/csm-docs/).


### VolumeGroupSnapshot Support
This driver now supports VolumeGroupSnapshot functionality as defined in CSI specification 1.11. This feature allows creating crash-consistent snapshots of multiple volumes simultaneously.

#### Key Features
- **CreateVolumeGroupSnapshot**: Create snapshots of multiple volumes simultaneously
- **DeleteVolumeGroupSnapshot**: Delete a group snapshot and all member snapshots
- **GetVolumeGroupSnapshot**: Retrieve information about a group snapshot
- **Write-Order Consistency**: All snapshots in the group are taken at the same point-in-time
- **CSI Spec 1.11 Compliance**: Full compliance with CSI specification requirements
66 changes: 62 additions & 4 deletions cmd/csi-powerstore/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (

"github.com/dell/csi-powerstore/v2/pkg/array"
"github.com/dell/csi-powerstore/v2/pkg/controller"
"github.com/dell/csi-powerstore/v2/pkg/groupcontroller"
"github.com/dell/csi-powerstore/v2/pkg/identifiers"
"github.com/dell/csi-powerstore/v2/pkg/identifiers/fs"
"github.com/dell/csi-powerstore/v2/pkg/identity"
Expand Down Expand Up @@ -99,8 +100,29 @@ func initilizeDriverConfigParams() {

var ManifestSemver string

// validateAndSetDRBindPort validates the CSM DR bind port environment variable
// and returns a valid port string, defaulting to ":8082" if invalid
func validateAndSetDRBindPort(envPort string) string {
defaultPort := ":8082"
if envPort == "" {
return defaultPort
}

port, err := strconv.Atoi(envPort)
if err != nil {
log.Warnf("Invalid CSM DR bind port '%s'. Must be a valid number (e.g., ':8082'). Using default :8082", envPort)
return defaultPort
}

if port < 1 || port > 65535 {
log.Warnf("Invalid CSM DR bind port '%d'. Must be between 1 and 65535. Using default :8082", port)
return defaultPort
}

return ":" + envPort
}

func main() {
log.SetLevel(csmlog.InfoLevel)
f := &fs.Fs{Util: &gofsutil.FS{}}

identifiers.RmSockFile(f)
Expand All @@ -113,6 +135,7 @@ func main() {

identityService := identity.NewIdentityService(identifiers.Name, ManifestSemver, identifiers.Manifest)
var controllerService *controller.Service
var groupControllerService *groupcontroller.Service
var nodeService *node.Service

mode := csictx.Getenv(context.Background(), gocsi.EnvVarMode)
Expand Down Expand Up @@ -144,11 +167,16 @@ func main() {
log.Fatalf("couldn't initialize controller service: %s", err.Error())
}

groupControllerService, err = initGroupControllerService(f, configPath)
if err != nil {
log.Fatalf("couldn't initialize group controller service: %s", err.Error())
}

arrayLocker = &controllerService.Locker
controllerService.IsCSMDREnabled = isCSMDREnabled
} else if strings.EqualFold(mode, "node") {
var err error
nodeService, err = initNodeService(f, configPath)
nodeService, err = initNodeServiceFunc(f, configPath)
if err != nil {
log.Fatalf("couldn't initialize node service: %s", err.Error())
}
Expand All @@ -159,8 +187,11 @@ func main() {

if isCSMDREnabled {
// Initialize CSM DR volume journal reconciler.
log.Infof("Initializing CSM-DR controller ")
_, err := drController.Initialize(nodeService, controllerService, arrayLocker, mode, nodeName, ":8080", false, ":8081")
drBindPort := validateAndSetDRBindPort(os.Getenv(identifiers.EnvCSMDRBindPort))

log.Infof("Initializing CSM-DR controller with bind port %s", drBindPort)

_, err := drController.Initialize(nodeService, controllerService, arrayLocker, mode, nodeName, drBindPort, false)
if err != nil {
log.Errorf("[METRO] Unable to initialize volume journal reconciler: %s", err.Error())
}
Expand All @@ -177,6 +208,10 @@ func main() {
if err != nil {
log.Fatalf("couldn't initialize arrays in controller service: %s", err.Error())
}
err = groupControllerService.UpdateArrays(configPath, f)
if err != nil {
log.Fatalf("couldn't initialize arrays in group controller service: %s", err.Error())
}
} else if strings.EqualFold(mode, "node") {
err := nodeService.UpdateArrays(configPath, f)
if err != nil {
Expand Down Expand Up @@ -205,6 +240,7 @@ func main() {
storageProvider := &gocsi.StoragePlugin{
Controller: controllerService,
Identity: identityService,
GroupController: groupControllerService,
Node: nodeService,
Interceptors: InterceptorsList,
RegisterAdditionalServers: controllerService.RegisterAdditionalServers,
Expand All @@ -220,6 +256,8 @@ func main() {
runCSIPlugin(storageProvider)
}

var initNodeServiceFunc = initNodeService

var runCSIPlugin = func(storageProvider *gocsi.StoragePlugin) {
gocsi.Run(context.Background(), identifiers.Name,
"A PowerStore Container Storage Interface (CSI) Driver",
Expand Down Expand Up @@ -289,6 +327,26 @@ func initControllerService(f fs.Interface, configPath string) (*controller.Servi
return cs, nil
}

func initGroupControllerService(f fs.Interface, configPath string) (*groupcontroller.Service, error) {
log.Infof("Initializing group controller service with config path: %s", configPath)
gcs := &groupcontroller.Service{
Fs: f,
}

err := gcs.UpdateArrays(configPath, f)
if err != nil {
return nil, fmt.Errorf("couldn't initialize arrays in group controller service: %v", err)
}

err = gcs.Init()
if err != nil {
return nil, fmt.Errorf("couldn't create group controller service: %v", err)
}
log.Infof("Done initializing group controller service with config path: %s", configPath)

return gcs, nil
}

func initNodeService(f fs.Interface, configPath string) (*node.Service, error) {
ns := &node.Service{
Fs: f,
Expand Down
Loading
Loading