1 # -*- coding: utf-8 -*-
2 # for localized messages
4 from re import compile as re_compile
5 from os import path as os_path, symlink, listdir, unlink, readlink, remove
7 from enigma import eTimer
8 from Components.Console import Console
9 from Components.Harddisk import harddiskmanager #global harddiskmanager
10 from Tools.Directories import isMount, removeDir, createDir
12 from xml.etree.cElementTree import parse as cet_parse
14 XML_FSTAB = "/etc/enigma2/automounts.xml"
17 """Manages Mounts declared in a XML-Document."""
20 self.restartConsole = Console()
21 self.MountConsole = Console()
22 self.removeConsole = Console()
23 self.activeMountsCounter = 0
27 self.timer.callback.append(self.mountTimeout)
29 self.getAutoMountPoints()
31 def getAutoMountPoints(self, callback = None):
32 # Initialize mounts to empty list
35 self.activeMountsCounter = 0
37 if not os_path.exists(XML_FSTAB):
39 tree = cet_parse(XML_FSTAB).getroot()
41 def getValue(definitions, default):
44 # How many definitions are present
45 Len = len(definitions)
46 return Len > 0 and definitions[Len-1].text or default
47 # Config is stored in "mountmanager" element
49 for nfs in tree.findall("nfs"):
50 for mount in nfs.findall("mount"):
51 data = { 'isMounted': False, 'active': False, 'ip': False, 'sharename': False, 'sharedir': False, 'username': False, \
52 'password': False, 'mounttype' : False, 'options' : False, 'hdd_replacement' : False }
54 data['mounttype'] = 'nfs'.encode("UTF-8")
55 data['active'] = getValue(mount.findall("active"), False).encode("UTF-8")
56 if data["active"] == 'True' or data["active"] == True:
57 self.activeMountsCounter +=1
58 data['hdd_replacement'] = getValue(mount.findall("hdd_replacement"), "False").encode("UTF-8")
59 data['ip'] = getValue(mount.findall("ip"), "192.168.0.0").encode("UTF-8")
60 data['sharedir'] = getValue(mount.findall("sharedir"), "/exports/").encode("UTF-8")
61 data['sharename'] = getValue(mount.findall("sharename"), "MEDIA").encode("UTF-8")
62 data['options'] = getValue(mount.findall("options"), "rw,nolock").encode("UTF-8")
64 self.automounts[data['sharename']] = data
66 print "[MountManager] Error reading Mounts:", e
67 # Read out CIFS Mounts
68 for nfs in tree.findall("cifs"):
69 for mount in nfs.findall("mount"):
70 data = { 'isMounted': False, 'active': False, 'ip': False, 'sharename': False, 'sharedir': False, 'username': False, \
71 'password': False, 'mounttype' : False, 'options' : False, 'hdd_replacement' : False }
73 data['mounttype'] = 'cifs'.encode("UTF-8")
74 data['active'] = getValue(mount.findall("active"), False).encode("UTF-8")
75 if data["active"] == 'True' or data["active"] == True:
76 self.activeMountsCounter +=1
77 data['hdd_replacement'] = getValue(mount.findall("hdd_replacement"), "False").encode("UTF-8")
78 data['ip'] = getValue(mount.findall("ip"), "192.168.0.0").encode("UTF-8")
79 data['sharedir'] = getValue(mount.findall("sharedir"), "/exports/").encode("UTF-8")
80 data['sharename'] = getValue(mount.findall("sharename"), "MEDIA").encode("UTF-8")
81 data['options'] = getValue(mount.findall("options"), "rw,nolock").encode("UTF-8")
82 data['username'] = getValue(mount.findall("username"), "guest").encode("UTF-8")
83 data['password'] = getValue(mount.findall("password"), "").encode("UTF-8")
84 print "CIFSMOUNT",data
85 self.automounts[data['sharename']] = data
87 print "[MountManager] Error reading Mounts:", e
89 print "[AutoMount.py] -getAutoMountPoints:self.automounts -->",self.automounts
90 if len(self.automounts) == 0:
91 print "[AutoMount.py] self.automounts without mounts",self.automounts
92 if callback is not None:
95 for sharename, sharedata in self.automounts.items():
96 self.CheckMountPoint(sharedata, callback)
98 def CheckMountPoint(self, data, callback):
99 print "[AutoMount.py] CheckMountPoint"
100 print "[AutoMount.py] activeMounts:--->",self.activeMountsCounter
101 if not self.MountConsole:
102 self.MountConsole = Console()
105 if self.activeMountsCounter == 0:
106 print "self.automounts without active mounts",self.automounts
107 if data['active'] == 'False' or data['active'] is False:
108 path = '/media/net/'+ data['sharename']
109 umountcmd = 'umount -f '+ path
110 print "[AutoMount.py] UMOUNT-CMD--->",umountcmd
111 self.MountConsole.ePopen(umountcmd, self.CheckMountPointFinished, [data, callback])
113 if data['active'] == 'False' or data['active'] is False:
114 path = '/media/net/'+ data['sharename']
115 self.command = 'umount -f '+ path
117 if data['active'] == 'True' or data['active'] is True:
118 path = '/media/net/'+ data['sharename']
119 if os_path.exists(path) is False:
121 tmpsharedir = data['sharedir'].replace(" ", "\\ ")
122 if tmpsharedir[-1:] == "$":
123 tmpdir = tmpsharedir.replace("$", "\\$")
126 if data['mounttype'] == 'nfs':
127 if not os_path.ismount(path):
128 tmpcmd = 'mount -t nfs -o tcp,'+ data['options'] +',rsize=8192,wsize=8192 ' + data['ip'] + ':' + tmpsharedir + ' ' + path
129 self.command = tmpcmd.encode("UTF-8")
131 if data['mounttype'] == 'cifs':
132 if not os_path.ismount(path):
133 tmpusername = data['username'].replace(" ", "\\ ")
134 tmpcmd = 'mount -t cifs -o '+ data['options'] +',iocharset=utf8,rsize=8192,wsize=8192,username='+ tmpusername + ',password='+ data['password'] + ' //' + data['ip'] + '/' + tmpsharedir + ' ' + path
135 self.command = tmpcmd.encode("UTF-8")
137 if self.command is not None:
138 print "[AutoMount.py] U/MOUNTCMD--->",self.command
139 self.MountConsole.ePopen(self.command, self.CheckMountPointFinished, [data, callback])
141 self.CheckMountPointFinished(None,None, [data, callback])
143 def CheckMountPointFinished(self, result, retval, extra_args):
144 print "[AutoMount.py] CheckMountPointFinished"
145 print "[AutoMount.py] result",result
146 print "[AutoMount.py] retval",retval
147 (data, callback ) = extra_args
148 print "LEN",len(self.MountConsole.appContainers)
149 path = '/media/net/'+ data['sharename']
150 print "PATH im CheckMountPointFinished",path
151 if os_path.exists(path):
152 if os_path.ismount(path):
153 if self.automounts.has_key(data['sharename']):
154 self.automounts[data['sharename']]['isMounted'] = True
155 desc = data['sharename']
156 if self.automounts[data['sharename']]['hdd_replacement'] == 'True': #hdd replacement hack
157 self.makeHDDlink(path)
158 harddiskmanager.addMountedPartition(path, desc)
160 if self.automounts.has_key(data['sharename']):
161 self.automounts[data['sharename']]['isMounted'] = False
162 if os_path.exists(path):
163 if not os_path.ismount(path):
165 harddiskmanager.removeMountedPartition(path)
167 if self.MountConsole:
168 if len(self.MountConsole.appContainers) == 0:
169 if callback is not None:
170 self.callback = callback
171 self.timer.startLongTimer(10)
173 def makeHDDlink(self, path):
174 hdd_dir = '/media/hdd'
175 print "[AutoMount.py] symlink %s %s" % (path, hdd_dir)
176 if os_path.islink(hdd_dir):
177 if readlink(hdd_dir) != path:
179 symlink(path, hdd_dir)
180 elif isMount(hdd_dir) is False:
181 if os_path.isdir(hdd_dir):
184 symlink(path, hdd_dir)
186 print "[AutoMount.py] add symlink fails!"
187 if os_path.exists(hdd_dir + '/movie') is False:
188 createDir(hdd_dir + '/movie')
190 def rm_rf(self, d): # only for removing the ipkg stuff from /media/hdd subdirs
191 for path in (os_path.join(d,f) for f in listdir(d)):
192 if os_path.isdir(path):
198 def mountTimeout(self):
200 if self.MountConsole:
201 if len(self.MountConsole.appContainers) == 0:
202 print "self.automounts after mounting",self.automounts
203 if self.callback is not None:
206 def getMountsList(self):
207 return self.automounts
209 def getMountsAttribute(self, mountpoint, attribute):
210 if self.automounts.has_key(mountpoint):
211 if self.automounts[mountpoint].has_key(attribute):
212 return self.automounts[mountpoint][attribute]
215 def setMountsAttribute(self, mountpoint, attribute, value):
216 print "setting for mountpoint", mountpoint, "attribute", attribute, " to value", value
217 if self.automounts.has_key(mountpoint):
218 self.automounts[mountpoint][attribute] = value
220 def writeMountsConfig(self):
221 # Generate List in RAM
222 list = ['<?xml version="1.0" ?>\n<mountmanager>\n']
224 for sharename, sharedata in self.automounts.items():
225 if sharedata['mounttype'] == 'nfs':
226 list.append('<nfs>\n')
227 list.append(' <mount>\n')
228 list.append(''.join([" <active>", str(sharedata['active']), "</active>\n"]))
229 list.append(''.join([" <hdd_replacement>", str(sharedata['hdd_replacement']), "</hdd_replacement>\n"]))
230 list.append(''.join([" <ip>", sharedata['ip'], "</ip>\n"]))
231 list.append(''.join([" <sharename>", sharedata['sharename'], "</sharename>\n"]))
232 list.append(''.join([" <sharedir>", sharedata['sharedir'], "</sharedir>\n"]))
233 list.append(''.join([" <options>", sharedata['options'], "</options>\n"]))
234 list.append(' </mount>\n')
235 list.append('</nfs>\n')
237 if sharedata['mounttype'] == 'cifs':
238 list.append('<cifs>\n')
239 list.append(' <mount>\n')
240 list.append(''.join([" <active>", str(sharedata['active']), "</active>\n"]))
241 list.append(''.join([" <hdd_replacement>", str(sharedata['hdd_replacement']), "</hdd_replacement>\n"]))
242 list.append(''.join([" <ip>", sharedata['ip'], "</ip>\n"]))
243 list.append(''.join([" <sharename>", sharedata['sharename'], "</sharename>\n"]))
244 list.append(''.join([" <sharedir>", sharedata['sharedir'], "</sharedir>\n"]))
245 list.append(''.join([" <options>", sharedata['options'], "</options>\n"]))
246 list.append(''.join([" <username>", sharedata['username'], "</username>\n"]))
247 list.append(''.join([" <password>", sharedata['password'], "</password>\n"]))
248 list.append(' </mount>\n')
249 list.append('</cifs>\n')
251 # Close Mountmanager Tag
252 list.append('</mountmanager>\n')
254 # Try Saving to Flash
257 file = open(XML_FSTAB, "w")
258 file.writelines(list)
260 print "[AutoMount.py] Error Saving Mounts List:", e
265 def stopMountConsole(self):
266 if self.MountConsole is not None:
267 self.MountConsole = None
269 def removeMount(self, mountpoint, callback = None):
270 print "[AutoMount.py] removing mount: ",mountpoint
271 self.newautomounts = {}
272 for sharename, sharedata in self.automounts.items():
273 if sharename is not mountpoint.strip():
274 self.newautomounts[sharename] = sharedata
275 self.automounts.clear()
276 self.automounts = self.newautomounts
277 if not self.removeConsole:
278 self.removeConsole = Console()
279 path = '/media/net/'+ mountpoint
280 umountcmd = 'umount -f '+ path
281 print "[AutoMount.py] UMOUNT-CMD--->",umountcmd
282 self.removeConsole.ePopen(umountcmd, self.removeMountPointFinished, [path, callback])
284 def removeMountPointFinished(self, result, retval, extra_args):
285 print "[AutoMount.py] removeMountPointFinished"
286 print "[AutoMount.py] result",result
287 print "[AutoMount.py] retval",retval
288 (path, callback ) = extra_args
289 if os_path.exists(path):
290 if not os_path.ismount(path):
292 harddiskmanager.removeMountedPartition(path)
294 if self.removeConsole:
295 if len(self.removeConsole.appContainers) == 0:
296 if callback is not None:
297 self.callback = callback
298 self.timer.startLongTimer(10)
301 # currently unused autofs support stuff
303 class AutoMount_Unused:
306 self.restartConsole = Console()
307 self.MountConsole = Console()
308 self.activeMountsCounter = 0
309 self.getAutoMountPoints()
312 def regExpMatch(self, pattern, string):
316 return pattern.search(string).group()
317 except AttributeError:
320 # helper function to convert ips from a sring to a list of ints
321 def convertIP(self, ip):
322 strIP = ip.split('.')
329 def getAutoMountPoints(self, callback = None):
330 print "[AutoMount.py] getAutoMountPoints"
333 self.activeMountsCounter = 0
336 fp = file('/etc/auto.network', 'r')
337 automounts = fp.readlines()
340 print "[AutoMount.py] /etc/auto.network - opening failed"
342 ipRegexp = '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
343 cifsIpLinePattern = re_compile('://' + ipRegexp + '/')
344 nfsIpLinePattern = re_compile(ipRegexp + ':/')
345 ipPattern = re_compile(ipRegexp)
346 for line in automounts:
347 print "[AutoMount.py] Line:",line
348 split = line.strip().split('\t',2)
351 if len(split) == 2 and split[0][0] == '*':
354 data = { 'isMounted': False, 'active': False, 'ip': False, 'sharename': False, 'sharedir': False, 'username': False, 'password': False, 'mounttype' : False, 'options' : False }
356 if split[0][0] == '#':
357 data['active'] = False
358 currshare = split[0][1:]
359 data['sharename'] = currshare
361 data['active'] = True
362 self.activeMountsCounter +=1
364 data['sharename'] = currshare
365 if '-fstype=cifs' in split[1]:
366 data['mounttype'] = 'cifs'
367 options = split[1][split[1].index('-fstype=cifs')+13 : split[1].index(',user=')]
368 if options is not None:
369 data['options'] = options
370 if 'user=' in split[1]:
371 username = split[1][split[1].index(',user=')+6 : split[1].index(',pass=')]
372 if username is not None:
373 data['username'] = username
374 if 'pass=' in split[1]:
375 password = split[1][split[1].index(',pass=')+6 : ]
376 if password is not None:
377 data['password'] = password
378 ip = self.regExpMatch(ipPattern, self.regExpMatch(cifsIpLinePattern, split[2]))
381 sharedir = split[2][split[2].index(ip)+len(ip)+1 : ]
382 if sharedir is not None:
383 tmpsharedir = sharedir.replace("\\ ", " ")
384 if tmpsharedir[-2:] == "\$":
385 tmpdir = tmpsharedir.replace("\$", "$")
387 data['sharedir'] = tmpsharedir
389 if '-fstype=nfs' in split[1]:
390 data['mounttype'] = 'nfs'
391 options = split[1][split[1].index('-fstype=nfs')+12 : ]
392 if options is not None:
393 data['options'] = options
394 ip = self.regExpMatch(ipPattern, self.regExpMatch(nfsIpLinePattern, split[2]))
397 sharedir = split[2][split[2].index(ip)+len(ip)+1 : ]
398 if sharedir is not None:
399 tmpsharedir = sharedir.replace("\\ ", " ")
400 if tmpsharedir[-2:] == "\$":
401 tmpdir = tmpsharedir.replace("\$", "$")
403 data['sharedir'] = tmpsharedir
405 self.automounts[currshare] = data
406 if len(self.automounts) == 0:
407 print "[AutoMount.py] self.automounts without mounts",self.automounts
408 if callback is not None:
411 #print "automounts",self.automounts
412 for sharename, sharedata in self.automounts.items():
413 self.CheckMountPoint(sharedata, callback)
415 def CheckMountPoint(self, data, callback):
416 print "[AutoMount.py] CheckMountPoint"
417 if not self.MountConsole:
418 self.MountConsole = Console()
419 print "[AutoMount.py] activeMounts--->",self.activeMountsCounter
420 if self.activeMountsCounter == 0:
421 #if data['active'] is False:
422 if self.MountConsole:
423 if len(self.MountConsole.appContainers) == 0:
424 print "self.automounts without active mounts",self.automounts
425 if callback is not None:
428 if data['mounttype'] == 'nfs' and data['active'] is True:
429 path = '/tmp/'+ data['sharename']
430 if os_path.exists(path) is False:
432 tmpsharedir = data['sharedir'].replace(" ", "\\ ")
433 if tmpsharedir[-1:] == "$":
434 tmpdir = tmpsharedir.replace("$", "\\$")
436 nfscmd = 'mount -o nolock -t nfs ' + data['ip'] + ':' + tmpsharedir + ' ' + path
437 print "[AutoMount.py] nfsscmd--->",nfscmd
438 self.MountConsole.ePopen(nfscmd, self.CheckMountPointFinished, [data, callback])
439 if data['mounttype'] == 'cifs' and data['active'] is True:
440 self.activeMountsCounter +=1
441 path = '/tmp/'+ data['sharename']
442 if os_path.exists(path) is False:
444 tmpsharedir = data['sharedir'].replace(" ", "\\ ")
445 if tmpsharedir[-1:] == "$":
446 tmpdir = tmpsharedir.replace("$", "\\$")
448 cifscmd = 'mount -t cifs -o rw,username='+ data['username'] + ',password='+ data['password'] + ' //' + data['ip'] + '/' + tmpsharedir + ' ' + path
449 print "[AutoMount.py] cifscmd--->",cifscmd
450 self.MountConsole.ePopen(cifscmd, self.CheckMountPointFinished, [data, callback])
452 def CheckMountPointFinished(self, result, retval, extra_args):
453 print "[AutoMount.py] CheckMountPointFinished"
454 (data, callback ) = extra_args
455 path = '/tmp/'+ data['sharename']
456 if not self.MountConsole:
457 self.MountConsole = Console()
458 if os_path.ismount(path):
459 if self.automounts.has_key(data['sharename']):
460 self.automounts[data['sharename']]['isMounted'] = True
462 if self.automounts.has_key(data['sharename']):
463 self.automounts[data['sharename']]['isMounted'] = False
464 umountcmd = 'umount /tmp/'+ data['sharename']
465 self.MountConsole.ePopen(umountcmd, self.CleanMountPointFinished, [data, callback])
467 def CleanMountPointFinished(self, result, retval, extra_args):
468 print "[AutoMount.py] CleanMountPointFinished"
469 (data, callback ) = extra_args
470 path = '/tmp/'+ data['sharename']
471 if os_path.exists(path):
473 if self.MountConsole:
474 if len(self.MountConsole.appContainers) == 0:
475 print "self.automounts after mountcheck",self.automounts
476 if callback is not None:
479 def getMountsList(self):
480 return self.automounts
482 def getMountsAttribute(self, mountpoint, attribute):
483 if self.automounts.has_key(mountpoint):
484 if self.automounts[mountpoint].has_key(attribute):
485 return self.automounts[mountpoint][attribute]
488 def setMountsAttribute(self, mountpoint, attribute, value):
489 print "setting for mountpoint", mountpoint, "attribute", attribute, " to value", value
490 if self.automounts.has_key(mountpoint):
491 self.automounts[mountpoint][attribute] = value
493 def removeMount(self, mountpoint):
494 self.newautomounts = {}
495 #self.automounts[currshare] = data
496 print "[AutoMount.py] removing mount: ",mountpoint
497 for sharename, sharedata in self.automounts.items():
498 if sharename is not mountpoint.strip():
499 self.newautomounts[sharename] = sharedata
500 self.automounts.clear()
501 self.automounts = self.newautomounts
503 def writeMountsConfig(self):
504 fp = file('/etc/auto.network', 'w')
505 fp.write("# automatically generated by enigma 2\n# do NOT change manually!\n\n")
506 for sharename, sharedata in self.automounts.items():
507 if sharedata['mounttype'] == 'nfs':
508 if sharedata['active'] is False:
509 fp.write("#" + sharedata['sharename'] + "\t")
511 fp.write( sharedata['sharename'] + "\t")
512 fp.write( "-fstype=nfs," + sharedata['options'] + "\t")
513 fp.write(sharedata['ip'] + ":")
514 tmpsharedir = sharedata['sharedir'].replace(" ", "\\ ")
515 if tmpsharedir[-1:] == "$":
516 tmpdir = tmpsharedir.replace("$", "\\$")
518 fp.write( tmpsharedir + "\n")
519 if sharedata['mounttype'] == 'cifs':
520 if sharedata['active'] is False:
521 fp.write("#" + sharedata['sharename'] + "\t")
523 fp.write( sharedata['sharename'] + "\t")
524 fp.write( "-fstype=cifs," + sharedata['options'] + ",")
525 fp.write( "user=" + sharedata['username'] + ",")
526 fp.write( "pass=" + sharedata['password'] + "\t://")
527 fp.write(sharedata['ip'] + "/")
528 tmpsharedir = sharedata['sharedir'].replace(" ", "\\ ")
529 if tmpsharedir[-1:] == "$":
530 tmpdir = tmpsharedir.replace("$", "\\$")
532 fp.write( tmpsharedir + "\n")
536 def restartAutoFS(self,callback = None):
537 print "[AutoMount.py] restartAutoFS "
538 self.restartConsole = Console()
540 self.commands.append("/etc/init.d/autofs stop")
541 self.commands.append("killall -9 automount")
542 self.commands.append("rm -rf /var/run/autofs")
543 self.commands.append("/etc/init.d/autofs start")
544 self.restartConsole.eBatch(self.commands, self.restartAutoFSFinished, callback, debug=True)
546 def restartAutoFSFinished(self,extra_args):
547 print "[AutoMount.py] restartAutoFSFinished "
548 ( callback ) = extra_args
549 if callback is not None:
552 def stopMountConsole(self):
553 if self.MountConsole is not None:
554 self.MountConsole = None """
556 iAutoMount = AutoMount()