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);
+      }
+    }
+  }
+}