New directory to store extra web accessible things of an instance
authorFrederic Massart <fred@moodle.com>
Tue, 4 Nov 2014 10:15:16 +0000 (18:15 +0800)
committerFrederic Massart <fred@moodle.com>
Tue, 4 Nov 2014 10:15:16 +0000 (18:15 +0800)
mdk/commands/doctor.py
mdk/config-dist.json
mdk/workplace.py

index f33ddeb..60352ab 100644 (file)
@@ -92,6 +92,13 @@ class DoctorCommand(Command):
             }
         ),
         (
+            ['--symlink'],
+            {
+                'action': 'store_true',
+                'help': 'Check the symlinks of the instances'
+            }
+        ),
+        (
             ['--wwwroot'],
             {
                 'action': 'store_true',
@@ -131,6 +138,10 @@ class DoctorCommand(Command):
         if args.wwwroot or allChecks:
             self.wwwroot(args)
 
+        # Check instances symlink
+        if args.symlink or allChecks:
+            self.symlink(args)
+
         # Check the branches
         if args.branch or allChecks:
             self.branch(args)
@@ -251,6 +262,19 @@ class DoctorCommand(Command):
                     print '    Creating %s' % d
                     mkdir(d, 0777)
 
+        if not self._checkWorkplace():
+            return
+
+        # Checking extra directory.
+        instances = self.Wp.list()
+        for identifier in instances:
+            d = self.Wp.getPath(identifier, 'extra')
+            if not os.path.isdir(d):
+                print '  %s does not exist' % d
+                if args.fix:
+                    print '    Creating %s' % d
+                    mkdir(d, 0777)
+
     def hi(self, args):
         """I wonder what is the purpose of this...
 
@@ -263,6 +287,32 @@ class DoctorCommand(Command):
         else:
             print '<em>Hi</em>'
 
+    def symlink(self, args):
+        """Check that the symlinks exist"""
+
+        print 'Checking symlinks'
+
+        if not self._checkWorkplace():
+            return
+
+        instances = self.Wp.list()
+        for identifier in instances:
+
+            wwwLink = os.path.join(self.Wp.www, identifier)
+            if not os.path.exists(wwwLink):
+                print '  Missing link to www for %s' % (identifier)
+                if args.fix:
+                    print '    Creating www symlink for %s' % (identifier)
+                    os.symlink(self.Wp.getPath(identifier, 'www'), wwwLink)
+
+            extraLink = os.path.join(self.Wp.getMdkWebDir(), identifier)
+            if not os.path.exists(extraLink):
+                print '  Missing link to extra for %s' % (identifier)
+                if args.fix:
+                    print '    Creating extra symlink for %s' % (identifier)
+                    os.symlink(self.Wp.getPath(identifier, 'extra'), extraLink)
+
+
     def remotes(self, args):
         """Check that the correct remotes are used"""
 
index e47f6c4..1b8d97b 100644 (file)
         "launchSleep": 5
     },
 
-    // The name of the data directory
+    // The name of the data directory (in dirs.storage/instanceName/)
     "dataDir": "moodledata",
-    // The name of the www directory
+    // The name of the www directory (in dirs.storage/instanceName/)
     "wwwDir": "moodle",
+    // The name of the extra directory, it will be used to store different things of an instance (in dirs.storage/instanceName/)
+    "extraDir": "extra",
+    // The name of the web accessible directory that MDK uses to give access to the extraDirs (created in dirs.www/).
+    "mdkDir": "mdk",
 
     // The default engine to use when not specified
     "defaultEngine": "mysqli",
index 7a5f226..2e84e5b 100644 (file)
@@ -36,13 +36,38 @@ C = Conf()
 
 class Workplace(object):
 
-    def __init__(self, path=None, wwwDir=None, dataDir=None):
+    """The name of the directory that contains the PHP files"""
+    wwwDir = None
+
+    """The name of the directory that contains Moodle data"""
+    dataDir = None
+
+    """The name of the directory that contains extra files"""
+    extraDir = None
+
+    """The name of the directory that makes extraDir web accessible, see getMdkWebDir"""
+    mdkDir = None
+
+    """The path to the storage directory"""
+    path = None
+
+    """The path to MDK cache"""
+    cache = None
+
+    """The path to the web accessible directory"""
+    www = None
+
+    def __init__(self, path=None, wwwDir=None, dataDir=None, extraDir=None, mdkDir=None):
         if path == None:
             path = C.get('dirs.storage')
         if wwwDir == None:
             wwwDir = C.get('wwwDir')
         if dataDir == None:
             dataDir = C.get('dataDir')
+        if extraDir == None:
+            extraDir = C.get('extraDir')
+        if mdkDir == None:
+            mdkDir = C.get('mdkDir')
 
         # Directory paths
         self.path = os.path.abspath(os.path.realpath(os.path.expanduser(path)))
@@ -55,6 +80,8 @@ class Workplace(object):
         # Directory names
         self.wwwDir = wwwDir
         self.dataDir = dataDir
+        self.extraDir = extraDir
+        self.mdkDir = mdkDir
 
     def checkCachedClones(self, stable=True, integration=True):
         """Clone the official repository in a local cache"""
@@ -94,10 +121,15 @@ class Workplace(object):
         if name == None:
             name = self.generateInstanceName(version, integration=integration)
 
-        installDir = os.path.join(self.path, name)
-        wwwDir = os.path.join(installDir, self.wwwDir)
-        dataDir = os.path.join(installDir, self.dataDir)
+        if name == self.mdkDir:
+            raise Exception('A Moodle instance cannot be called \'%s\', this is a reserved word.' % self.mdkDir)
+
+        installDir = self.getPath(name)
+        wwwDir = self.getPath(name, 'www')
+        dataDir = self.getPath(name, 'data')
+        extraDir = self.getPath(name, 'extra')
         linkDir = os.path.join(self.www, name)
+        extraLinkDir = os.path.join(self.getMdkWebDir(), name)
 
         if self.isMoodle(name):
             raise CreateException('The Moodle instance %s already exists' % name)
@@ -109,6 +141,7 @@ class Workplace(object):
         mkdir(installDir, 0755)
         mkdir(wwwDir, 0755)
         mkdir(dataDir, 0777)
+        mkdir(extraDir, 0777)
 
         repository = self.getCachedRemote(integration)
 
@@ -124,6 +157,12 @@ class Workplace(object):
         else:
             os.symlink(wwwDir, linkDir)
 
+        # Symlink to extra.
+        if os.path.isfile(extraLinkDir) or os.path.isdir(extraLinkDir):
+            logging.warning('Could not create symbolic link. Please manually create: ln -s %s %s' % (extraDir, extraLinkDir))
+        else:
+            os.symlink(extraDir, extraLinkDir)
+
         # Symlink to dataDir in wwwDir
         if type(C.get('symlinkToData')) == str:
             linkDataDir = os.path.join(wwwDir, C.get('symlinkToData'))
@@ -177,6 +216,14 @@ class Workplace(object):
             except Exception:
                 pass
 
+        # Delete the extra dir symlink
+        link = os.path.join(self.getMdkWebDir(), name)
+        if os.path.islink(link):
+            try:
+                os.remove(link)
+            except Exception:
+                pass
+
         # Delete db
         DB = M.dbo()
         dbname = M.get('dbname')
@@ -229,6 +276,14 @@ class Workplace(object):
         else:
             return os.path.join(self.cache, 'moodle.git')
 
+    def getMdkWebDir(self):
+        """Return (and create) the special MDK web directory."""
+        mdkExtra = os.path.join(self.www, self.mdkDir)
+        if not os.path.exists(mdkExtra):
+            mkdir(mdkExtra, 0777)
+
+        return mdkExtra
+
     def getPath(self, name, mode=None):
         """Returns the path of an instance base on its name"""
         base = os.path.join(self.path, name)
@@ -236,6 +291,8 @@ class Workplace(object):
             return os.path.join(base, self.wwwDir)
         elif mode == 'data':
             return os.path.join(base, self.dataDir)
+        elif mode == 'extra':
+            return os.path.join(base, self.extraDir)
         else:
             return base