Skip to content

Commit

Permalink
reuse node instances by using nodefactory
Browse files Browse the repository at this point in the history
  • Loading branch information
joergsteffens committed Sep 19, 2015
1 parent 3d86ae6 commit cdd8218
Show file tree
Hide file tree
Showing 18 changed files with 176 additions and 59 deletions.
10 changes: 7 additions & 3 deletions bareos/fuse/node/backups.py
Expand Up @@ -6,12 +6,16 @@
from bareos.fuse.node.job import Job

class Backups(Directory):
def __init__(self, bsock, name, client):
super(Backups, self).__init__(bsock, name)
def __init__(self, root, name, client):
super(Backups, self).__init__(root, name)
self.client = client

@classmethod
def get_id(cls, name, client):
return client

def do_update(self):
data = self.bsock.call("llist backups client=%s" % (self.client))
backups = data['backups']
for i in backups:
self.add_subnode(Job(self.bsock, i))
self.add_subnode(Job, i)
37 changes: 31 additions & 6 deletions bareos/fuse/node/base.py
Expand Up @@ -14,24 +14,41 @@ class Base(object):
"""
Base class for filesystem nodes.
"""
def __init__(self, bsock, name):
def __init__(self, root, name):
self.logger = logging.getLogger()
self.bsock = bsock
self.root = root
self.bsock = root.bsock
self.set_name(name)
self.stat = fuse.Stat()
self.content = None
self.subnodes = {}
self.subnodes_old = self.subnodes.copy()
self.static = False
self.lastupdate = None
# timeout for caching
self.cache_timeout = timedelta(seconds=60)

@classmethod
def get_id(cls, *args, **kwargs):
"""
To enable reusing instances at different places in the filesystem,
this method must be overwritten
and return a unique id (string) for this class.
The parameter of this must be identical to the parameter
of the __init__ method must be identical to the parameter of get_id,
except that the "root" parameter is excluded.
"""
return None

def get_name(self):
return self.name

def set_name(self, name):
self.name = name

def set_static(self, value=True):
self.static = value

def getattr(self, path):
self.logger.debug("%s(\"%s\")" % (str(self), str(path)))
result = -errno.ENOENT
Expand Down Expand Up @@ -98,10 +115,14 @@ def read(self, path, size, offset):
result = self.subnodes[topdir].read(path, size, offset)
return result

def add_subnode(self, obj):
name = obj.get_name()
def add_subnode(self, classtype, *args, **kwargs):
instance = self.root.factory.get_instance(classtype, *args, **kwargs)
name = instance.get_name()
if not self.subnodes.has_key(name):
self.subnodes[name] = obj
self.subnodes[name] = instance
else:
if self.subnodes_old.has_key(name):
del(self.subnodes_old[name])

def update(self):
# update status, content, ...
Expand All @@ -113,7 +134,12 @@ def update(self):
elif not self.static and (self.lastupdate + self.cache_timeout) < now:
diff = now - self.lastupdate
self.logger.debug("reason: non-static and timeout (%d seconds)" % (diff.seconds))
# store current subnodes
# and delete all not updated subnodes after do_update()
self.subnodes_old = self.subnodes.copy()
self.do_update()
for i in self.subnodes_old.keys():
del(self.subnodes[name])
self.lastupdate = datetime.now()
else:
self.logger.debug("skipped")
Expand All @@ -126,4 +152,3 @@ def _convert_date_bareos_unix(self, bareosdate):
unixtimestamp = int(DateParser.parse(bareosdate).strftime("%s"))
self.logger.debug( "unix timestamp: %d" % (unixtimestamp))
return unixtimestamp

12 changes: 8 additions & 4 deletions bareos/fuse/node/bvfsdir.py
Expand Up @@ -10,24 +10,28 @@
import logging

class BvfsDir(Directory):
def __init__(self, bsock, name, jobid, pathid, directory = None):
super(BvfsDir, self).__init__(bsock, name)
def __init__(self, root, name, jobid, pathid, directory = None):
super(BvfsDir, self).__init__(root, name)
self.jobid = jobid
self.pathid = pathid
self.static = True
if directory:
self.set_stat(directory['stat'])

@classmethod
def get_id(cls, name, jobid, pathid, directory = None):
return str(pathid)

def do_update(self):
directories = self.get_directories(self.pathid)
files = self.get_files(self.pathid)
for i in directories:
if i['name'] != "." and i['name'] != "..":
name = i['name'].rstrip('/')
pathid = i['pathid']
self.add_subnode(BvfsDir(self.bsock, name, self.jobid, pathid, i))
self.add_subnode(BvfsDir, name, self.jobid, pathid, i)
for i in files:
self.add_subnode(BvfsFile(self.bsock, i))
self.add_subnode(BvfsFile, i)

def get_directories(self, pathid):
if pathid == None:
Expand Down
8 changes: 6 additions & 2 deletions bareos/fuse/node/bvfsfile.py
Expand Up @@ -6,8 +6,12 @@
import stat

class BvfsFile(File):
def __init__(self, bsock, file):
super(BvfsFile, self).__init__(bsock, file['name'], content = None)
def __init__(self, root, file):
super(BvfsFile, self).__init__(root, file['name'], content = None)
self.file = file
self.static = True
self.set_stat(self.file['stat'])

@classmethod
def get_id(cls, file):
return str(file['fileid'])
12 changes: 8 additions & 4 deletions bareos/fuse/node/client.py
Expand Up @@ -7,9 +7,13 @@
from bareos.fuse.node.jobslist import JobsList

class Client(Directory):
def __init__(self, bsock, name):
super(Client, self).__init__(bsock, name)
def __init__(self, root, name):
super(Client, self).__init__(root, name)

@classmethod
def get_id(cls, name):
return name

def do_update(self):
self.add_subnode(Backups(self.bsock, "backups", client=self.get_name()))
self.add_subnode(JobsList(self.bsock, "jobs", "client=%s" % (self.get_name())))
self.add_subnode(Backups, "backups", client=self.get_name())
self.add_subnode(JobsList, "jobs", "client=%s" % (self.get_name()))
10 changes: 7 additions & 3 deletions bareos/fuse/node/clients.py
Expand Up @@ -6,12 +6,16 @@
from bareos.fuse.node.directory import Directory

class Clients(Directory):
def __init__(self, bsock, name):
super(Clients, self).__init__(bsock, name)
def __init__(self, root, name):
super(Clients, self).__init__(root, name)

@classmethod
def get_id(cls, name):
return "unique"

def do_update(self):
data = self.bsock.call(".clients")
clients = data['clients']
for i in clients:
name = i['name']
self.add_subnode(Client(self.bsock, name))
self.add_subnode(Client, name)
4 changes: 2 additions & 2 deletions bareos/fuse/node/directory.py
Expand Up @@ -11,8 +11,8 @@ class Directory(Base):
"""
Directory node.
"""
def __init__(self, bsock, name):
super(Directory, self).__init__(bsock, name)
def __init__(self, root, name):
super(Directory, self).__init__(root, name)
self.defaultdirs = [ ".", ".." ]
self.stat.st_mode = stat.S_IFDIR | 0755
self.stat.st_nlink = len(self.defaultdirs)
Expand Down
4 changes: 2 additions & 2 deletions bareos/fuse/node/file.py
Expand Up @@ -12,8 +12,8 @@ class File(Base):
"""
File node.
"""
def __init__(self, bsock, name, content = ""):
super(File, self).__init__(bsock, name)
def __init__(self, root, name, content = ""):
super(File, self).__init__(root, name)
self.content = content
self.stat.st_mode = stat.S_IFREG | 0444
self.stat.st_nlink = 1
Expand Down
17 changes: 11 additions & 6 deletions bareos/fuse/node/job.py
Expand Up @@ -12,9 +12,9 @@
import stat

class Job(Directory):
def __init__(self, bsock, job):
def __init__(self, root, job):
self.job = job
super(Job, self).__init__(bsock, self.get_name())
super(Job, self).__init__(root, self.get_name())
try:
self.stat.st_ctime = self._convert_date_bareos_unix(self.job['starttime'])
except KeyError:
Expand All @@ -23,16 +23,21 @@ def __init__(self, bsock, job):
self.stat.st_mtime = self._convert_date_bareos_unix(self.job['realendtime'])
except KeyError:
pass
if job['jobstatus'] == 'T' or job['jobstatus'] == 'E' or job['jobstatus'] == 'W':
self.set_static()

@classmethod
def get_id(cls, job):
return job['jobid']

def get_name(self):
# TODO: adapt list backups to include name
try:
name = "jobid={jobid}_client={client}_name={name}_level={level}_status={jobstatus}".format(**self.job)
except KeyError:
name = "jobid={jobid}_level={level}_status={jobstatus}".format(**self.job)
return name

def do_update(self):
self.add_subnode(File(self.bsock, name="info.txt", content = pformat(self.job) + "\n"))
self.add_subnode(JobLog(self.bsock, self.job))
self.add_subnode(BvfsDir(self.bsock, "data", self.job['jobid'], None))
self.add_subnode(File, name="info.txt", content = pformat(self.job) + "\n")
self.add_subnode(JobLog, self.job)
self.add_subnode(BvfsDir, "data", self.job['jobid'], None)
11 changes: 8 additions & 3 deletions bareos/fuse/node/joblog.py
Expand Up @@ -5,10 +5,15 @@
from bareos.fuse.node.file import File

class JobLog(File):
def __init__(self, bsock, job):
super(JobLog, self).__init__(bsock, "joblog.txt")
def __init__(self, root, job):
super(JobLog, self).__init__(root, "joblog.txt")
self.job = job
# TODO: static when job is finished
if job['jobstatus'] == 'T' or job['jobstatus'] == 'E' or job['jobstatus'] == 'W':
self.set_static()

@classmethod
def get_id(cls, job):
return job['jobid']

def do_update(self):
jobid = self.job['jobid']
Expand Down
13 changes: 9 additions & 4 deletions bareos/fuse/node/jobs.py
Expand Up @@ -7,13 +7,18 @@
from bareos.fuse.node.jobsname import JobsName

class Jobs(Directory):
def __init__(self, bsock, name):
super(Jobs, self).__init__(bsock, name)
def __init__(self, root, name):
super(Jobs, self).__init__(root, name)
self.static = True

@classmethod
def get_id(cls, name):
return "unique"

def do_update(self):
data = self.bsock.call(".jobs")
jobs = data['jobs']
for i in jobs:
self.add_subnode(JobsName(self.bsock, i['name']))
self.add_subnode(JobsList(self.bsock, "all"))
self.add_subnode(JobsName, i['name'])
self.add_subnode(JobsList, "all")
self.add_subnode(JobsList, "running", "jobstatus=running")
10 changes: 7 additions & 3 deletions bareos/fuse/node/jobslist.py
Expand Up @@ -6,12 +6,16 @@
from bareos.fuse.node.job import Job

class JobsList(Directory):
def __init__(self, bsock, name, selector = ''):
super(JobsList, self).__init__(bsock, name)
def __init__(self, root, name, selector = ''):
super(JobsList, self).__init__(root, name)
self.selector = selector

@classmethod
def get_id(cls, name, selector = ''):
return selector

def do_update(self):
data = self.bsock.call("llist jobs %s" % (self.selector))
jobs = data['jobs']
for i in jobs:
self.add_subnode(Job(self.bsock, i))
self.add_subnode(Job, i)
10 changes: 7 additions & 3 deletions bareos/fuse/node/jobsname.py
Expand Up @@ -6,12 +6,16 @@
from bareos.fuse.node.job import Job

class JobsName(Directory):
def __init__(self, bsock, name):
super(JobsName, self).__init__(bsock, "job="+str(name))
def __init__(self, root, name):
super(JobsName, self).__init__(root, "job="+str(name))
self.jobname=name

@classmethod
def get_id(cls, name):
return name

def do_update(self):
data = self.bsock.call("llist job=%s" % (self.jobname))
jobs = data['jobs']
for i in jobs:
self.add_subnode(Job(self.bsock, i))
self.add_subnode(Job, i)
14 changes: 9 additions & 5 deletions bareos/fuse/node/volume.py
Expand Up @@ -9,11 +9,15 @@
from pprint import pformat

class Volume(Directory):
def __init__(self, bsock, volume):
super(Volume, self).__init__(bsock, volume['volumename'])
def __init__(self, root, volume):
super(Volume, self).__init__(root, volume['volumename'])
self.volume = volume

@classmethod
def get_id(cls, volume):
return volume['volumename']

def do_update(self):
self.add_subnode(File(self.bsock, name="info.txt", content=pformat(self.volume) + "\n"))
self.add_subnode(JobsList(self.bsock, name="jobs", selector="volume=%s" % (self.name)))
self.add_subnode(VolumeStatus(self.bsock, name="volume", volume=self.volume))
self.add_subnode(File, name="info.txt", content=pformat(self.volume) + "\n")
self.add_subnode(JobsList, name="jobs", selector="volume=%s" % (self.name))
self.add_subnode(VolumeStatus, name="volume", volume=self.volume)
10 changes: 7 additions & 3 deletions bareos/fuse/node/volumes.py
Expand Up @@ -6,12 +6,16 @@
from bareos.fuse.node.volume import Volume

class Volumes(Directory):
def __init__(self, bsock, name):
super(Volumes, self).__init__(bsock, name)
def __init__(self, root, name):
super(Volumes, self).__init__(root, name)

@classmethod
def get_id(cls, name):
return "unique"

def do_update(self):
data = self.bsock.call("llist volumes all")
volumes = data['volumes']
for i in volumes:
volume = i['volumename']
self.add_subnode(Volume(self.bsock, i))
self.add_subnode(Volume, i)
8 changes: 6 additions & 2 deletions bareos/fuse/node/volumestatus.py
Expand Up @@ -21,12 +21,16 @@ class VolumeStatus(File):
"Error": 0000,
}

def __init__(self, bsock, name, volume):
super(VolumeStatus, self).__init__(bsock, None, None)
def __init__(self, root, name, volume):
super(VolumeStatus, self).__init__(root, None, None)
self.volume = volume
self.update_stat()
self.set_name( "status=%s" % (self.volume['volstatus']) )

@classmethod
def get_id(cls, name, volume):
return volume['mediaid']

def do_update(self):
volumename = self.volume['volumename']
data = self.bsock.call( "llist volume=%s" % (volumename) )
Expand Down

0 comments on commit cdd8218

Please sign in to comment.