First stab at a package to create the console server
[invirt/packages/invirt-console.git] / files / usr / bin / sipb-xen-consolefs
1 #!/usr/bin/python
2
3 import fuse
4 from fuse import Fuse
5
6 from time import time
7
8 import stat     # for file properties
9 import os         # for filesystem modes (O_RDONLY, etc)
10 import errno   # for error number codes (ENOENT, etc)
11                            # - note: these must be returned as negatives
12
13 fuse.fuse_python_api = (0, 2)
14
15 machines = ['moo17', 'remus']
16 realpath = "/home/machines/"
17 uid = 1000
18
19 def dirFromList(list):
20         """
21         Return a properly formatted list of items suitable to a directory listing.
22         ['a', 'b', 'c'] => [('a', 0), ('b', 0), ('c', 0)]
23         """
24         return [(x, 0) for x in list]
25
26 def getDepth(path):
27         """
28         Return the depth of a given path, zero-based from root ('/')
29         """
30         if path == '/':
31                 return 0
32         else:
33                 return path.count('/')
34
35 def getParts(path):
36         """
37         Return the slash-separated parts of a given path as a list
38         """
39         if path == '/':
40                 return ['/']
41         else:
42                 return path[1:].split('/')
43
44 class MyStat:
45         def __init__(self):
46                 self.st_mode = 0
47                 self.st_ino = 0
48                 self.st_dev = 0
49                 self.st_nlink = 0
50                 self.st_uid = uid
51                 self.st_gid = 0
52                 self.st_size = 0
53                 self.st_atime = 0
54                 self.st_mtime = 0
55                 self.st_ctime = 0
56         
57         def toTuple(self):
58                 return (self.st_mode, self.st_ino, self.st_dev, self.st_nlink, self.st_uid, self.st_gid, self.st_size, self.st_atime, self.st_mtime, self.st_ctime)
59
60 class ConsoleFS(Fuse):
61         """
62         """
63         
64         def __init__(self, *args, **kw):
65                 Fuse.__init__(self, *args, **kw)
66                 print 'Init complete.'
67         
68         def mirrorPath(self, path):
69                 return realpath + "/".join(getParts(path)[1:])
70         
71         def getattr(self, path):
72                 """
73                 - st_mode (protection bits)
74                 - st_ino (inode number)
75                 - st_dev (device)
76                 - st_nlink (number of hard links)
77                 - st_uid (user ID of owner)
78                 - st_gid (group ID of owner)
79                 - st_size (size of file, in bytes)
80                 - st_atime (time of most recent access)
81                 - st_mtime (time of most recent content modification)
82                 - st_ctime (platform dependent; time of most recent metadata change on Unix,
83                                         or the time of creation on Windows).
84                 """
85                 
86                 print "*** getattr: " + path
87                 
88                 depth = getDepth(path)
89                 parts = getParts(path)
90                 
91                 st = MyStat()
92                 if path == '/':
93                         st.st_mode = stat.S_IFDIR | 0755
94                         st.st_nlink = 2
95                 elif depth == 1:
96                         if parts[-1] in machines:
97                                 st.st_mode = stat.S_IFDIR | 0755
98                                 st.st_nlink = 2
99                         else:
100                                 return -errno.ENOENT
101                 elif depth == 2 and parts[-1] == '.k5login':
102                         st.st_mode = stat.S_IFREG | 0444
103                         st.st_nlink = 1
104                         st.st_size = 17
105                 else:
106                         st = os.lstat(self.mirrorPath(path))
107                 return st.toTuple()
108         
109         def readdir(self, path, offset):
110                 print '*** readdir', path, offset
111                 if path == '/':
112                         for r in  ['.', '..']+machines:
113                                 yield fuse.Direntry(r)
114                 elif getDepth(path) == 1:
115                         for r in set(os.listdir(self.mirrorPath(path)) + ['.k5login']):
116                                 yield fuse.Direntry(r)
117                 else:
118                         for r in os.listdir(self.mirrorPath(path)):
119                                 yield fuse.Direntry(r)
120         
121         def read ( self, path, length, offset ):
122                 print '*** read', path, length, offset
123                 
124                 if getDepth(path) < 2:
125                         return -errno.ENOENT
126                 elif getParts(path)[1:] == ['.k5login']:
127                         pass
128                 else:
129                         fname = self.mirrorPath(path)
130                         if not os.path.isfile(fname):
131                                 return -errno.ENOENT
132                         else:
133                                 f = open(fname)
134                                 f.seek(offset)
135                                 return f.read(length)
136
137 if __name__ == '__main__':
138         usage="""
139 ConsoleFS [mount_path]
140 """
141         server = ConsoleFS()
142         server.flags = 0
143         server.main()