Always try to chcon the volume dir to svirt_sandbox_file_t, regardless
of whether or not the dir previously existed. This is required to avoid
SELinux denials that occur when the volume dir is created prior to
starting the node and it doesn't have the correct SELinux label.
| ... | ... |
@@ -110,12 +110,13 @@ func (c *NodeConfig) initializeVolumeDir(ce commandExecutor, path string) (strin |
| 110 | 110 |
if err := os.MkdirAll(rootDirectory, 0750); err != nil {
|
| 111 | 111 |
return "", fmt.Errorf("Couldn't create kubelet volume root directory '%s': %s", rootDirectory, err)
|
| 112 | 112 |
} |
| 113 |
- if chconPath, err := ce.LookPath("chcon"); err != nil {
|
|
| 114 |
- glog.V(2).Infof("Couldn't locate 'chcon' to set the kubelet volume root directory SELinux context: %s", err)
|
|
| 115 |
- } else {
|
|
| 116 |
- if err := ce.Run(chconPath, "-t", "svirt_sandbox_file_t", rootDirectory); err != nil {
|
|
| 117 |
- glog.Warningf("Error running 'chcon' to set the kubelet volume root directory SELinux context: %s", err)
|
|
| 118 |
- } |
|
| 113 |
+ } |
|
| 114 |
+ // always try to chcon, in case the volume dir existed prior to the node starting |
|
| 115 |
+ if chconPath, err := ce.LookPath("chcon"); err != nil {
|
|
| 116 |
+ glog.V(2).Infof("Couldn't locate 'chcon' to set the kubelet volume root directory SELinux context: %s", err)
|
|
| 117 |
+ } else {
|
|
| 118 |
+ if err := ce.Run(chconPath, "-t", "svirt_sandbox_file_t", rootDirectory); err != nil {
|
|
| 119 |
+ glog.Warningf("Error running 'chcon' to set the kubelet volume root directory SELinux context: %s", err)
|
|
| 119 | 120 |
} |
| 120 | 121 |
} |
| 121 | 122 |
return rootDirectory, nil |
| ... | ... |
@@ -39,55 +39,55 @@ func TestInitializeVolumeDir(t *testing.T) {
|
| 39 | 39 |
} |
| 40 | 40 |
defer os.RemoveAll(parentDir) |
| 41 | 41 |
|
| 42 |
- testCases := []struct {
|
|
| 43 |
- chconFound bool |
|
| 44 |
- chconRunErr error |
|
| 45 |
- removeVolumeDir bool |
|
| 42 |
+ volumeDir := path.Join(parentDir, "somedir") |
|
| 43 |
+ |
|
| 44 |
+ testCases := map[string]struct {
|
|
| 45 |
+ chconFound bool |
|
| 46 |
+ chconRunErr error |
|
| 47 |
+ dirAlreadyExists bool |
|
| 46 | 48 |
}{
|
| 47 |
- {chconFound: false, removeVolumeDir: true},
|
|
| 48 |
- {chconFound: true, chconRunErr: nil, removeVolumeDir: true},
|
|
| 49 |
- {chconFound: true, chconRunErr: errors.New("e"), removeVolumeDir: true},
|
|
| 50 |
- {removeVolumeDir: false},
|
|
| 49 |
+ "no chcon": {chconFound: false},
|
|
| 50 |
+ "have chcon": {chconFound: true},
|
|
| 51 |
+ "chcon error": {chconFound: true, chconRunErr: errors.New("e")},
|
|
| 52 |
+ "volume dir already exists": {chconFound: true, dirAlreadyExists: true},
|
|
| 51 | 53 |
} |
| 52 | 54 |
|
| 53 |
- for i, testCase := range testCases {
|
|
| 55 |
+ for name, testCase := range testCases {
|
|
| 54 | 56 |
ce := &fakeCommandExecutor{
|
| 55 | 57 |
commandFound: testCase.chconFound, |
| 56 | 58 |
commandErr: testCase.chconRunErr, |
| 57 | 59 |
} |
| 58 |
- nc := &NodeConfig{VolumeDir: path.Join(parentDir, "somedir")}
|
|
| 59 | 60 |
|
| 60 |
- if testCase.removeVolumeDir {
|
|
| 61 |
- if err := os.RemoveAll(nc.VolumeDir); err != nil {
|
|
| 62 |
- t.Fatalf("%d: Error removing volume dir: %s", i, err)
|
|
| 61 |
+ if testCase.dirAlreadyExists {
|
|
| 62 |
+ if err := os.MkdirAll(volumeDir, 0750); err != nil {
|
|
| 63 |
+ t.Fatalf("%s: error creating volume dir: %v", name, err)
|
|
| 64 |
+ } |
|
| 65 |
+ } else {
|
|
| 66 |
+ if err := os.RemoveAll(volumeDir); err != nil {
|
|
| 67 |
+ t.Fatalf("%s: error removing volume dir: %v", name, err)
|
|
| 63 | 68 |
} |
| 64 | 69 |
} |
| 65 | 70 |
|
| 71 |
+ nc := &NodeConfig{VolumeDir: volumeDir}
|
|
| 66 | 72 |
path, err := nc.initializeVolumeDir(ce, nc.VolumeDir) |
| 67 | 73 |
|
| 68 |
- if testCase.removeVolumeDir {
|
|
| 69 |
- if !ce.lookCalled {
|
|
| 70 |
- t.Fatalf("%d: expected look for chcon", i)
|
|
| 71 |
- } |
|
| 72 |
- if !testCase.chconFound && ce.runCalled {
|
|
| 73 |
- t.Fatalf("%d: unexpected run after chcon not found", i)
|
|
| 74 |
- } |
|
| 75 |
- if testCase.chconFound && !ce.runCalled {
|
|
| 76 |
- t.Fatalf("%d: expected chcon run", i)
|
|
| 77 |
- } |
|
| 78 |
- if err != nil {
|
|
| 79 |
- t.Fatalf("%d: unexpected err: %s", i, err)
|
|
| 80 |
- } |
|
| 81 |
- if path != nc.VolumeDir {
|
|
| 82 |
- t.Fatalf("%d:, expected path(%s) == nc.VolumeDir(%s)", i, path, nc.VolumeDir)
|
|
| 83 |
- } |
|
| 84 |
- } else {
|
|
| 85 |
- if ce.lookCalled {
|
|
| 86 |
- t.Fatalf("%d: unexpected look for chcon with reused volume dir", i)
|
|
| 87 |
- } |
|
| 88 |
- if ce.runCalled {
|
|
| 89 |
- t.Fatalf("%d: unexpected run for chcon with reused volume dir", i)
|
|
| 90 |
- } |
|
| 74 |
+ if !ce.lookCalled {
|
|
| 75 |
+ t.Errorf("%s: expected look for chcon", name)
|
|
| 76 |
+ } |
|
| 77 |
+ if !testCase.chconFound && ce.runCalled {
|
|
| 78 |
+ t.Errorf("%s: unexpected run after chcon not found", name)
|
|
| 79 |
+ } |
|
| 80 |
+ if testCase.chconFound && !ce.runCalled {
|
|
| 81 |
+ t.Errorf("%s: expected chcon run", name)
|
|
| 82 |
+ } |
|
| 83 |
+ if err != nil {
|
|
| 84 |
+ t.Errorf("%s: unexpected err: %s", name, err)
|
|
| 85 |
+ } |
|
| 86 |
+ if path != nc.VolumeDir {
|
|
| 87 |
+ t.Errorf("%s:, expected path(%s) == nc.VolumeDir(%s)", name, path, nc.VolumeDir)
|
|
| 88 |
+ } |
|
| 89 |
+ if _, err := os.Stat(path); err != nil {
|
|
| 90 |
+ t.Errorf("%s: expected volume dir to exist: %v", name, err)
|
|
| 91 | 91 |
} |
| 92 | 92 |
} |
| 93 | 93 |
} |