Change:
<!-- Thanks for filing an issue! Before hitting the button, please answer these questions.--Is this a request for help? (If yes, you should use our troubleshooting guide and community support channels, see ): no What keywords did you search in Kubernetes issues before filing this one? (If you have found any duplicates, you should instead reply there.): azurefile azurefile 0777 Is this a BUG REPORT or FEATURE REQUEST? (choose one): FEATURE REQUEST Kubernetes version (use ): Client Version: version.Info{Major:"1", Minor:"4", GitVersion:"v1.4.5", GitCommit:"", GitTreeState:"clean", BuildDate:"2016-10-29T01:38:40Z", GoVersion:"go1.6.3", Compiler:"gc", Platform:"linux/amd64"} Server Version: version.Info{Major:"1", Minor:"4", GitVersion:"v1.4.5", GitCommit:"", GitTreeState:"clean", BuildDate:"2016-10-29T01:32:42Z", GoVersion:"go1.6.3", Compiler:"gc", Platform:"linux/amd64"} Environment: Cloud provider or hardware configuration: Microsoft Azure Container Service OS (e.g. from /etc/os-release): Ubuntu 16.04 LTS Kernel (e.g. ): Linux 4.4.0-28-generic -Ubuntu SMP Fri Jun 24 10:09:13 UTC 2016 x8664 x8664 x8664 GNU/Linux What happened: I attempted to set up an Azure File Volume using the built-in volume type azureFile. Everything works, except that the files and directories defaults to permission 0777, always. When I tried to manually mount within the container, I could customise dirmode and filemode, meaning that this change should be possible. Reading the source code confirms it - dirmode=0777 and filemode=0777 seem hardcoded. What you expected to happen: Being able to supply dirmode and filemode to the mount. e.g. How to reproduce it (as minimally and precisely as possible): N/A. This is a feature request. Anything else do we need to know: N/A
This is a big requirement, using an azure file volume for postgresql for instance fails due to permissions as initdb tries to change the permissions to be less restrictive but is unable to.
Evaluating compatibility between a certain setup of a volume mount and an arbitrary piece of software would be the responsibility of the integrator, wouldn't it? It seems a big requirement for K8s itself to have to ensure PostgreSQL can do what it wants. An integrator who tries to use Azure File Storage for PostgreSQL should know better to mount with the correct permission.
The point is that you cannot mount with permissions, they're hard coded to 0777.
Ah. Yeah. Sorry for misunderstanding the comment above. Let's say it is an "important" requirement :)
/sig azure
/assign andyzhangx
I have a for this, use mount options in storage class, below is an example:
Has this change made it into any release yet? I can't seem to find it... Or was the issue resolved in some other way? I'm facing the issue you originally reported, i.e. using a pod volume to an azureFile, and it always mounting with filemode and dirmode of 0755... and I need it to be 0777. Is there a workaround? TIA.
azure file mountOptions feature is available from v1.8.5, here is the example :
Thanks -- I was still having trouble until I the storageClassName: "" to the claim... then realized I was hitting issue which I can avoid by setting storageClassName: "default" to both the pv and pvc, and now everything works. Thanks again!

Discussion:
} else { os.MkdirAll(dir, 0700) // parameters suggested by https://azure.microsoft.com/en-us/documentation/articles/storage-how-to-use-files-linux/ <del> options := []string{fmt.Sprintf("vers=3.0,username=%s,password=%s,dir_mode=0700,file_mode=0700", accountName, accountKey)} </del> <ins> options := []string{fmt.Sprintf("username=%s,password=%s", accountName, accountKey)} </ins> if b.readOnly { options = append(options, "ro") } mountOptions = volume.JoinMountOptions(b.mountOptions, options) <ins> mountOptions = appendDefaultMountOptions(mountOptions) </ins> } err = b.mounter.Mount(source, dir, "cifs", mountOptions)

package azure_file import ( <ins> "fmt" </ins> "io/ioutil" "os" "path" <ins> "reflect" </ins> "strings" "testing"

} } <ins> func TestAppendDefaultMountOptions(t *testing.T) { tests := []struct { options  []string expected []string }{ { options:  []string{"dir_mode=0777"}, expected: []string{"dir_mode=0777", fmt.Sprintf("%s=%s", fileMode, defaultFileMode), fmt.Sprintf("%s=%s", vers, defaultVers)}, }, { options:  []string{"file_mode=0777"}, expected: []string{"file_mode=0777", fmt.Sprintf("%s=%s", dirMode, defaultDirMode), fmt.Sprintf("%s=%s", vers, defaultVers)}, }, { options:  []string{"vers=2.1"}, expected: []string{"vers=2.1", fmt.Sprintf("%s=%s", fileMode, defaultFileMode), fmt.Sprintf("%s=%s", dirMode, defaultDirMode)}, }, { options:  []string{""}, expected: []string{"", fmt.Sprintf("%s=%s", fileMode, defaultFileMode), fmt.Sprintf("%s=%s", dirMode, defaultDirMode), fmt.Sprintf("%s=%s", vers, defaultVers)}, }, { options:  []string{"file_mode=0777", "dir_mode=0777"}, expected: []string{"file_mode=0777", "dir_mode=0777", fmt.Sprintf("%s=%s", vers, defaultVers)}, }, } for _, test := range tests { result := appendDefaultMountOptions(test.options) if !reflect.DeepEqual(result, test.expected) { t.Errorf("input: %q, appendDefaultMountOptions result: %q, expected: %q", test.options, result, test.expected) } } } </ins>

import ( "fmt" <ins> "strings" </ins> v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors"

"k8s.io/kubernetes/pkg/volume" ) <ins> const ( fileMode        = "file_mode" dirMode         = "dir_mode" vers            = "vers" defaultFileMode = "0700" defaultDirMode  = "0700" defaultVers     = "3.0" ) </ins> // Abstract interface to azure file operations. type azureUtil interface { GetAzureCredentials(host volume.VolumeHost, nameSpace, secretName string) (string, string, error)

} return secretName, err } <ins> // check whether mountOptions contain file_mode and dir_mode, if not, append default mode func appendDefaultMountOptions(mountOptions []string) []string { fileModeFlag := false dirModeFlag := false versFlag := false for _, mountOption := range mountOptions { if strings.HasPrefix(mountOption, fileMode) { fileModeFlag = true } if strings.HasPrefix(mountOption, dirMode) { dirModeFlag = true } if strings.HasPrefix(mountOption, vers) { versFlag = true } } allMountOptions := mountOptions if !fileModeFlag { allMountOptions = append(allMountOptions, fmt.Sprintf("%s=%s", fileMode, defaultFileMode)) } if !dirModeFlag { allMountOptions = append(allMountOptions, fmt.Sprintf("%s=%s", dirMode, defaultDirMode)) } if !versFlag { allMountOptions = append(allMountOptions, fmt.Sprintf("%s=%s", vers, defaultVers)) } return allMountOptions } </ins>