# 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")
-# TODO: for Giovanni
+
def read_keys():
- return "reading PLC users' public keys\n"
+ 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")
+ return f.read()
+
+def all_keys():
+ keys = read_keys()
+
+ files = {}
+ num = 0
+ for line in keys.split('\n'):
+ line = line.strip()
+ fields = line.split()
+ try:
+ name = fields[2]
+ files[name] = line
+ except:
+ num += 1
+ files["unnamed_key%d" % num] = 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: