#!/usr/bin/python # A FUSE filesystem implementation to provide a file interface for # vsys_publickeys VSYS script. To be used by OMF Resource Controller. # Usage: ./keys_fs.py /keys # ls /keys # cat /keys/all # NOTE: # Sliver has to have following ccapabilities set. # SECURE_MOUNT # BINARY_MOUNT # # we also depend on fuse and python-fuse packages. # import os import sys import stat import errno import fuse import fcntl import select from fuse import Fuse fuse.fuse_python_api = (0, 2) keys_dir = "/keys" all_ssh_keys = None all_ssh_keys_dict = None def read_keys(): global all_ssh_keys if all_ssh_keys: return all_ssh_keys fin = os.open("/vsys/publickeys.in", os.O_NONBLOCK | os.O_WRONLY) fout = os.open("/vsys/publickeys.out", os.O_NONBLOCK | os.O_RDONLY) in_flags = fcntl.fcntl(fin, fcntl.F_GETFL) out_flags = fcntl.fcntl(fin, fcntl.F_GETFL) res = select.select([fout], [], []) fcntl.fcntl(fin, fcntl.F_SETFL, in_flags & ~os.O_NONBLOCK) fcntl.fcntl(fout, fcntl.F_SETFL, out_flags & ~os.O_NONBLOCK) f = os.fdopen(fout, "r") all_ssh_keys = f.read() return all_ssh_keys def all_keys(): global all_ssh_keys_dict if all_ssh_keys_dict: return all_ssh_keys_dict keys = read_keys() files = {} num = 0 for line in keys.split('\n'): line = line.strip() if not line: continue filename = "" in_key = False in_name = False fields = line.split() for f in fields: f = f.strip() if f.startswith("ssh-"): in_key = True continue elif in_key: in_name = True in_key = False continue elif in_name: if filename: filename = "%s_%s" % (filename, f) else: filename = f if not filename: num += 1 files["unnamed_key%d" % num] = line else: files[filename] = "%s\n" % line return files class MyStat(fuse.Stat): def __init__(self): self.st_mode = 0 self.st_ino = 0 self.st_dev = 0 self.st_nlink = 0 self.st_uid = 0 self.st_gid = 0 self.st_size = 0 self.st_atime = 0 self.st_mtime = 0 self.st_ctime = 0 class KeyFS(Fuse): def __init__(self, *args, **kw): Fuse.__init__(self, *args, **kw) def getattr(self, path): st = MyStat() if path == '/': st.st_mode = stat.S_IFDIR | 0755 st.st_nlink = 2 elif os.path.basename(path) == "all": st.st_mode = stat.S_IFREG | 0444 st.st_nlink = 1 st.st_size = len(read_keys()) else: filename = os.path.basename(path) keys = all_keys() st.st_mode = stat.S_IFREG | 0444 st.st_nlink = 1 try: st.st_size = len(keys[filename]) except: st.st_size = 0 return st def readdir(self, path, offset): files = ['.', '..', "all"] keys = all_keys() files.extend(keys.keys()) for r in files: yield fuse.Direntry(r) def open(self, path, flags): accmode = os.O_RDONLY | os.O_WRONLY | os.O_RDWR if (flags & accmode) != os.O_RDONLY: return -errno.EACCES def read (self, path, size, offset): if os.path.basename(path) == "all": content = read_keys() else: filename = os.path.basename(path) keys = all_keys() content = keys[filename] slen = len(content) if offset < slen: if offset + size > slen: size = slen - offset buf = content[offset:offset+size] else: buf = '' return buf if __name__ == '__main__': fs = KeyFS() fs.multithreaded = 0 fs.parse(values=fs, errex=1) try: if fs.fuse_args.mount_expected(): os.chdir("/") except OSError: sys.stderr.write("can't enter root of underlying filesystem\n") sys.exit(1) fs.main()