# 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):
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):
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