You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@slider.apache.org by st...@apache.org on 2014/11/10 13:54:33 UTC
incubator-slider git commit: SLIDER-622 test for FS permissions on
minicluster
Repository: incubator-slider
Updated Branches:
refs/heads/feature/SLIDER-622-windows [created] c52493f94
SLIDER-622 test for FS permissions on minicluster
Project: http://git-wip-us.apache.org/repos/asf/incubator-slider/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-slider/commit/c52493f9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-slider/tree/c52493f9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-slider/diff/c52493f9
Branch: refs/heads/feature/SLIDER-622-windows
Commit: c52493f94dcaeea9d8f382e2bee5bebf93744351
Parents: 7974ffd
Author: Steve Loughran <st...@apache.org>
Authored: Mon Nov 10 12:53:57 2014 +0000
Committer: Steve Loughran <st...@apache.org>
Committed: Mon Nov 10 12:53:57 2014 +0000
----------------------------------------------------------------------
.../other/TestFilesystemPermissions.groovy | 256 +++++++++++++++++++
1 file changed, 256 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/c52493f9/slider-core/src/test/groovy/org/apache/slider/other/TestFilesystemPermissions.groovy
----------------------------------------------------------------------
diff --git a/slider-core/src/test/groovy/org/apache/slider/other/TestFilesystemPermissions.groovy b/slider-core/src/test/groovy/org/apache/slider/other/TestFilesystemPermissions.groovy
new file mode 100644
index 0000000..7da51c1
--- /dev/null
+++ b/slider-core/src/test/groovy/org/apache/slider/other/TestFilesystemPermissions.groovy
@@ -0,0 +1,256 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.slider.other
+
+import groovy.io.FileType
+import groovy.transform.CompileStatic
+import groovy.util.logging.Slf4j
+import org.apache.hadoop.conf.Configuration
+import org.apache.hadoop.fs.AbstractFileSystem
+import org.apache.hadoop.fs.FileContext
+import org.apache.hadoop.fs.FileStatus
+import org.apache.hadoop.fs.FileUtil
+import org.apache.hadoop.fs.LocalFileSystem
+import org.apache.hadoop.fs.Path
+import org.apache.hadoop.fs.local.LocalFs
+import org.apache.hadoop.fs.permission.FsPermission
+import org.apache.hadoop.util.DiskChecker
+import org.apache.hadoop.yarn.exceptions.YarnRuntimeException
+import org.apache.hadoop.yarn.server.nodemanager.containermanager.localizer.ContainerLocalizer
+import org.apache.hadoop.yarn.server.nodemanager.containermanager.localizer.ResourceLocalizationService
+import org.apache.slider.test.YarnMiniClusterTestBase
+import org.junit.After
+import org.junit.Test
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+
+/**
+ * This test class exists to look at permissions of the filesystem, especially
+ * that created by Mini YARN clusters. On some windows jenkins machines,
+ * YARN actions were failing as the directories had the wrong permissions
+ * (i.e. too lax)
+ */
+@CompileStatic
+@Slf4j
+class TestFilesystemPermissions extends YarnMiniClusterTestBase {
+
+ static final Logger LOG = LoggerFactory.getLogger(TestFilesystemPermissions);
+
+ List<File> filesToDelete = []
+
+ @After
+ public void deleteFiles() {
+ filesToDelete.each { File f ->
+ FileUtil.fullyDelete(f, true)
+ }
+ }
+
+ @Test
+ public void testJavaFSOperations() throws Throwable {
+ assertNativeLibrariesPresent();
+ File subdir = testDir()
+ subdir.mkdir()
+ assert subdir.isDirectory()
+ assert FileUtil.canRead(subdir)
+ assert FileUtil.canWrite(subdir)
+ assert FileUtil.canExecute(subdir)
+ }
+
+ @Test
+ public void testDiskCheckerOperations() throws Throwable {
+ assertNativeLibrariesPresent();
+ File subdir = testDir()
+ subdir.mkdir()
+ DiskChecker checker = new DiskChecker()
+ checker.checkDir(subdir)
+ }
+
+ @Test
+ public void testDiskCheckerMkdir() throws Throwable {
+ assertNativeLibrariesPresent();
+ File subdir = testDir()
+ subdir.mkdirs()
+ DiskChecker checker = new DiskChecker()
+ checker.checkDir(subdir)
+ }
+
+ /**
+ * Get a test dir for this method; one that will be deleted on teardown
+ * @return a filename unique to this test method
+ */
+ File testDir() {
+ File parent = new File("target/testfspermissions")
+ parent.mkdir()
+ File testdir = new File(parent, methodName.methodName)
+ filesToDelete << testdir
+ return testdir;
+ }
+
+
+ @Test
+ public void testPermsMap() throws Throwable {
+ def dir = testDir()
+ def diruri = dir.toURI().toString()
+ def lfs = createLocalFS(dir, configuration)
+ getLocalDirsPathPermissionsMap(lfs, diruri)
+ }
+
+ @Test
+ public void testInitLocaldir() throws Throwable {
+ def dir = testDir()
+ def diruri = dir.toURI().toString()
+ def lfs = createLocalFS(dir, configuration)
+ initializeLocalDir(lfs, diruri)
+ def localDirs = getInitializedLocalDirs(lfs, [diruri])
+ assert localDirs.size() ==1
+ }
+
+
+ @Test
+ public void testValidateMiniclusterPerms() throws Throwable {
+ def numLocal = 1
+ def cluster = createMiniCluster("", configuration, 1, numLocal, 1, false)
+ def workDir = miniCluster.getTestWorkDir()
+ List<File> localdirs = [];
+ workDir.eachDir { File file ->
+ if (file.absolutePath.contains("-local")) {
+ // local dir
+ localdirs << file
+ }
+ }
+ assert localdirs.size() == numLocal
+ def lfs = createLocalFS(workDir, configuration)
+ localdirs.each { File file ->
+ checkLocalDir(lfs, file.toURI().toString())
+ }
+ }
+
+ FileContext createLocalFS(File dir, Configuration conf) {
+ return FileContext.getFileContext(dir.toURI(), conf)
+ }
+
+ /**
+ * extracted from ResourceLocalizationService
+ * @param lfs
+ * @param localDir
+ * @return perms map
+ * @see ResourceLocalizationService
+ */
+ private Map<Path, FsPermission> getLocalDirsPathPermissionsMap(
+ FileContext lfs,
+ String localDir) {
+ Map<Path, FsPermission> localDirPathFsPermissionsMap = new HashMap<Path, FsPermission>();
+
+ FsPermission defaultPermission =
+ FsPermission.getDirDefault().applyUMask(lfs.getUMask());
+ FsPermission nmPrivatePermission =
+ ResourceLocalizationService.NM_PRIVATE_PERM.applyUMask(lfs.getUMask());
+
+ Path userDir = new Path(localDir, ContainerLocalizer.USERCACHE);
+ Path fileDir = new Path(localDir, ContainerLocalizer.FILECACHE);
+ Path sysDir = new Path(
+ localDir,
+ ResourceLocalizationService.NM_PRIVATE_DIR);
+
+ localDirPathFsPermissionsMap.put(userDir, defaultPermission);
+ localDirPathFsPermissionsMap.put(fileDir, defaultPermission);
+ localDirPathFsPermissionsMap.put(sysDir, nmPrivatePermission);
+ return localDirPathFsPermissionsMap;
+ }
+
+ private boolean checkLocalDir(FileContext lfs, String localDir) {
+
+ Map<Path, FsPermission> pathPermissionMap =
+ getLocalDirsPathPermissionsMap(lfs, localDir);
+
+ for (Map.Entry<Path, FsPermission> entry : pathPermissionMap.entrySet()) {
+ FileStatus status;
+ status = lfs.getFileStatus(entry.getKey());
+
+ if (!status.getPermission().equals(entry.getValue())) {
+ String msg =
+ "Permissions incorrectly set for dir " + entry.getKey() +
+ ", should be " + entry.getValue() + ", actual value = " +
+ status.getPermission();
+ throw new YarnRuntimeException(msg);
+ }
+ }
+ return true;
+ }
+
+
+ private void initializeLocalDir(FileContext lfs, String localDir) {
+
+ Map<Path, FsPermission> pathPermissionMap =
+ getLocalDirsPathPermissionsMap(lfs, localDir);
+ for (Map.Entry<Path, FsPermission> entry : pathPermissionMap.entrySet()) {
+ FileStatus status;
+ try {
+ status = lfs.getFileStatus(entry.getKey());
+ }
+ catch (FileNotFoundException fs) {
+ status = null;
+ }
+
+ if (status == null) {
+ lfs.mkdir(entry.getKey(), entry.getValue(), true);
+ status = lfs.getFileStatus(entry.getKey());
+ }
+ FsPermission perms = status.getPermission();
+ if (!perms.equals(entry.getValue())) {
+ lfs.setPermission(entry.getKey(), entry.getValue());
+ }
+ }
+ }
+
+ synchronized private List<String> getInitializedLocalDirs(FileContext lfs,
+ List<String> dirs) {
+ List<String> checkFailedDirs = new ArrayList<String>();
+ for (String dir : dirs) {
+ try {
+ checkLocalDir(lfs, dir);
+ } catch (YarnRuntimeException e) {
+ checkFailedDirs.add(dir);
+ }
+ }
+ for (String dir : checkFailedDirs) {
+ LOG.info("Attempting to initialize " + dir);
+ initializeLocalDir(lfs, dir);
+ checkLocalDir(lfs, dir);
+ }
+ return dirs;
+ }
+
+
+ private void createDir(FileContext localFs, Path dir, FsPermission perm)
+ throws IOException {
+ if (dir == null) {
+ return;
+ }
+ try {
+ localFs.getFileStatus(dir);
+ } catch (FileNotFoundException e) {
+ createDir(localFs, dir.getParent(), perm);
+ localFs.mkdir(dir, perm, false);
+ if (!perm.equals(perm.applyUMask(localFs.getUMask()))) {
+ localFs.setPermission(dir, perm);
+ }
+ }
+ }
+}