From 615416ba63f60438058a349b3ae405935e97c6c9 Mon Sep 17 00:00:00 2001 From: Matthew Wong Date: Wed, 21 Dec 2016 17:11:18 -0500 Subject: [PATCH 1/2] Add rootsquash flag for enabling/disabling rootsquash --- docs/deployment.md | 1 + main.go | 3 ++- volume/export.go | 30 ++++++++++++++++++++++-------- volume/provision.go | 6 +++--- 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/docs/deployment.md b/docs/deployment.md index 1d30751..3b64041 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -181,4 +181,5 @@ The pod requires authorization to `list` all `StorageClasses`, `PersistentVolume * `run-server` - If the provisioner is responsible for running the NFS server, i.e. starting and stopping NFS Ganesha. Default true. * `use-ganesha` - If the provisioner will create volumes using NFS Ganesha (D-Bus method calls) as opposed to using the kernel NFS server ('exportfs'). If run-server is true, this must be true. Default true. * `grace-period` - NFS Ganesha grace period to use in seconds, from 0-180. If the server is not expected to survive restarts, i.e. it is running as a pod & its export directory is not persisted, this can be set to 0. Can only be set if both run-server and use-ganesha are true. Default 90. +* `root-squash` - If the provisioner will squash root users by adding the NFS Ganesha root_id_squash or kernel root_squash option to each export. Default false. * `enable-xfs-quota` - If the provisioner will set xfs quotas for each volume it provisions. Requires that the directory it creates volumes in ('/export') is xfs mounted with option prjquota/pquota, and that it has the privilege to run xfs_quota. Default false. diff --git a/main.go b/main.go index debf649..1754729 100644 --- a/main.go +++ b/main.go @@ -40,6 +40,7 @@ var ( runServer = flag.Bool("run-server", true, "If the provisioner is responsible for running the NFS server, i.e. starting and stopping NFS Ganesha. Default true.") useGanesha = flag.Bool("use-ganesha", true, "If the provisioner will create volumes using NFS Ganesha (D-Bus method calls) as opposed to using the kernel NFS server ('exportfs'). If run-server is true, this must be true. Default true.") gracePeriod = flag.Uint("grace-period", 90, "NFS Ganesha grace period to use in seconds, from 0-180. If the server is not expected to survive restarts, i.e. it is running as a pod & its export directory is not persisted, this can be set to 0. Can only be set if both run-server and use-ganesha are true. Default 90.") + rootSquash = flag.Bool("root-squash", false, "If the provisioner will squash root users by adding the NFS Ganesha root_id_squash or kernel root_squash option to each export. Default false.") enableXfsQuota = flag.Bool("enable-xfs-quota", false, "If the provisioner will set xfs quotas for each volume it provisions. Requires that the directory it creates volumes in ('/export') is xfs mounted with option prjquota/pquota, and that it has the privilege to run xfs_quota. Default false.") ) @@ -98,7 +99,7 @@ func main() { // Create the provisioner: it implements the Provisioner interface expected by // the controller - nfsProvisioner := vol.NewNFSProvisioner(exportDir, clientset, *useGanesha, ganeshaConfig, *enableXfsQuota) + nfsProvisioner := vol.NewNFSProvisioner(exportDir, clientset, *useGanesha, ganeshaConfig, *rootSquash, *enableXfsQuota) // Start the provision controller which will dynamically provision NFS PVs pc := controller.NewProvisionController(clientset, 15*time.Second, *provisioner, nfsProvisioner, serverVersion.GitVersion, false) diff --git a/volume/export.go b/volume/export.go index 9623244..31292cf 100644 --- a/volume/export.go +++ b/volume/export.go @@ -96,9 +96,9 @@ type ganeshaExporter struct { var _ exporter = &ganeshaExporter{} -func newGaneshaExporter(ganeshaConfig string) exporter { +func newGaneshaExporter(ganeshaConfig string, rootSquash bool) exporter { return &ganeshaExporter{ - genericExporter: *newGenericExporter(&ganeshaExportBlockCreator{}, ganeshaConfig, regexp.MustCompile("Export_Id = ([0-9]+);")), + genericExporter: *newGenericExporter(&ganeshaExportBlockCreator{rootSquash}, ganeshaConfig, regexp.MustCompile("Export_Id = ([0-9]+);")), } } @@ -140,18 +140,25 @@ func (e *ganeshaExporter) Unexport(volume *v1.PersistentVolume) error { return nil } -type ganeshaExportBlockCreator struct{} +type ganeshaExportBlockCreator struct { + // Whether to export with squash = root_id_squash, not no_root_squash + rootSquash bool +} var _ exportBlockCreator = &ganeshaExportBlockCreator{} // CreateBlock creates the text block to add to the ganesha config file. func (e *ganeshaExportBlockCreator) CreateExportBlock(exportId, path string) string { + squash := "no_root_squash" + if e.rootSquash { + squash = "root_id_squash" + } return "\nEXPORT\n{\n" + "\tExport_Id = " + exportId + ";\n" + "\tPath = " + path + ";\n" + "\tPseudo = " + path + ";\n" + "\tAccess_Type = RW;\n" + - "\tSquash = root_id_squash;\n" + + "\tSquash = " + squash + ";\n" + "\tSecType = sys;\n" + "\tFilesystem_id = " + exportId + "." + exportId + ";\n" + "\tFSAL {\n\t\tName = VFS;\n\t}\n}\n" @@ -163,9 +170,9 @@ type kernelExporter struct { var _ exporter = &kernelExporter{} -func newKernelExporter() exporter { +func newKernelExporter(rootSquash bool) exporter { return &kernelExporter{ - genericExporter: *newGenericExporter(&kernelExportBlockCreator{}, "/etc/exports", regexp.MustCompile("fsid=([0-9]+)")), + genericExporter: *newGenericExporter(&kernelExportBlockCreator{rootSquash}, "/etc/exports", regexp.MustCompile("fsid=([0-9]+)")), } } @@ -192,11 +199,18 @@ func (e *kernelExporter) Unexport(volume *v1.PersistentVolume) error { return nil } -type kernelExportBlockCreator struct{} +type kernelExportBlockCreator struct { + // Whether to export with option root_squash, not no_root_squash + rootSquash bool +} var _ exportBlockCreator = &kernelExportBlockCreator{} // CreateBlock creates the text block to add to the /etc/exports file. func (e *kernelExportBlockCreator) CreateExportBlock(exportId, path string) string { - return "\n" + path + " *(rw,insecure,root_squash,fsid=" + exportId + ")\n" + squash := "no_root_squash" + if e.rootSquash { + squash = "root_squash" + } + return "\n" + path + " *(rw,insecure," + squash + ",fsid=" + exportId + ")\n" } diff --git a/volume/provision.go b/volume/provision.go index 0afa03a..5353e4d 100644 --- a/volume/provision.go +++ b/volume/provision.go @@ -71,12 +71,12 @@ const ( nodeEnv = "NODE_NAME" ) -func NewNFSProvisioner(exportDir string, client kubernetes.Interface, useGanesha bool, ganeshaConfig string, enableXfsQuota bool) controller.Provisioner { +func NewNFSProvisioner(exportDir string, client kubernetes.Interface, useGanesha bool, ganeshaConfig string, rootSquash bool, enableXfsQuota bool) controller.Provisioner { var exporter exporter if useGanesha { - exporter = newGaneshaExporter(ganeshaConfig) + exporter = newGaneshaExporter(ganeshaConfig, rootSquash) } else { - exporter = newKernelExporter() + exporter = newKernelExporter(rootSquash) } var quotaer quotaer var err error From e92b3f11d9751289cd26a851c807ba6f2823c748 Mon Sep 17 00:00:00 2001 From: Matthew Wong Date: Wed, 21 Dec 2016 17:14:19 -0500 Subject: [PATCH 2/2] Update gid parameter with note about root squash --- docs/usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/usage.md b/docs/usage.md index ab2fff2..3fb5fa5 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -5,7 +5,7 @@ The nfs-provisioner has been deployed and is now watching for claims it should p Edit the `provisioner` field in `deploy/kube-config/class.yaml` to be the provisioner's name. Configure the `parameters`. ### Parameters -* `gid`: `"none"` or a [supplemental group](http://kubernetes.io/docs/user-guide/security-context/) like `"1001"`. NFS shares will be created with permissions such that only pods running with the supplemental group can read & write to the share. Or if `"none"`, anybody can write to the share. Default (if omitted) `"none"`. +* `gid`: `"none"` or a [supplemental group](http://kubernetes.io/docs/user-guide/security-context/) like `"1001"`. NFS shares will be created with permissions such that only pods running with the supplemental group can read & write to the share. Or if `"none"`, anybody can write to the share. This will only work in conjunction with the `root-squash` flag set true. Default (if omitted) `"none"`. Name the `StorageClass` however you like; the name is how claims will request this class. Create the class.