X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=omf_keys%2Fkey_fs.py;h=6993435c617f9b22ff72de79e5ce80d332cdcda2;hb=d1174660e3bb1370f5eb88968e562dba064dbbff;hp=80cdc429bcf9654fe517f355e9c95693744d628c;hpb=ebd3b79100d211ed27c4fb8ed80cb40533b0fc36;p=playground.git diff --git a/omf_keys/key_fs.py b/omf_keys/key_fs.py index 80cdc42..6993435 100644 --- a/omf_keys/key_fs.py +++ b/omf_keys/key_fs.py @@ -3,21 +3,93 @@ # 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 sys +import fcntl +import select from fuse import Fuse fuse.fuse_python_api = (0, 2) keys_dir = "/keys" -keys_file = os.path.join(keys_dir, "all") +all_ssh_keys = None +all_ssh_keys_dict = None -# TODO: for Giovanni def read_keys(): - return "reading PLC users' public keys\n" + 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): @@ -42,14 +114,26 @@ class KeyFS(Fuse): if path == '/': st.st_mode = stat.S_IFDIR | 0755 st.st_nlink = 2 - else: + 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): - for r in '.', '..', os.path.basename(keys_file): + files = ['.', '..', "all"] + keys = all_keys() + files.extend(keys.keys()) + for r in files: yield fuse.Direntry(r) def open(self, path, flags): @@ -58,13 +142,19 @@ class KeyFS(Fuse): return -errno.EACCES def read (self, path, size, offset): - keys = read_keys() - slen = len(keys) + 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 = keys[offset:offset+size] + buf = content[offset:offset+size] else: buf = '' return buf