Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/bareos/python-bareos.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoerg Steffens <joerg.steffens@dass-it.de>2015-09-08 12:05:20 +0300
committerJoerg Steffens <joerg.steffens@dass-it.de>2015-09-14 14:01:52 +0300
commitf019e6d98f9b604d359e472fc45c5dbcf012e38a (patch)
tree85f1bd2e133f7e0e8aabf90d81a389c69c4f2ebe
parent1341a8c08e134cf37017daafaae27a15f62d02e1 (diff)
bareos-fuse (bareosfs): initial version
initial, working version of bareos-fuse. Shows jobs, backuped files, clients and volumes.
-rw-r--r--bareos/bareosfuse.py208
-rw-r--r--bareos/bsock/bsock.py2
-rw-r--r--bareos/bsock/lowlevel.py4
-rw-r--r--bareos/fuse/__init__.py3
-rw-r--r--bareos/fuse/bareosfuse.py76
-rw-r--r--bareos/fuse/node/__init__.py5
-rw-r--r--bareos/fuse/node/bareosnodes.py169
-rw-r--r--bareos/fuse/node/base.py81
-rw-r--r--bareos/fuse/node/directory.py36
-rw-r--r--bareos/fuse/node/file.py24
-rw-r--r--bareos/fuse/root.py15
-rw-r--r--bareos/util/__init__.py1
-rw-r--r--bareos/util/path.py84
-rwxr-xr-xbin/bareos-fuse.py58
-rwxr-xr-xbin/bconsole-json.py11
-rwxr-xr-xbin/bconsole.py11
16 files changed, 537 insertions, 251 deletions
diff --git a/bareos/bareosfuse.py b/bareos/bareosfuse.py
deleted file mode 100644
index 2fc744c..0000000
--- a/bareos/bareosfuse.py
+++ /dev/null
@@ -1,208 +0,0 @@
-"""
-FUSE filesystem on bareos data.
-"""
-
-from bareos.bsock import BSockJson
-import errno
-import fuse
-import logging
-import os
-from pprint import pformat
-import stat
-
-fuse.fuse_python_api = (0, 2)
-
-TYPE_NONE = None
-TYPE_FILE = 1
-TYPE_DIR = 2
-
-
-class Base():
- def __init__(self, bsock):
- self.logger = logging.getLogger()
- self.bsock = bsock
- self.defaultdirs = [ ".", ".." ]
-
-
-class Jobs(Base):
-
- def getattr(self, path):
- self.logger.debug("Jobs \"%s\"" % (path))
- result = -errno.ENOENT
- st = fuse.Stat()
- part = path.split("/")
- if len(part) == 1:
- if part[0] == "":
- st.st_mode = stat.S_IFDIR | 0755
- #st.st_size = 4096
- number_entires = len(self.bsock.call("list jobs")['jobs'])
- st.st_nlink = len(self.defaultdirs) + 1
- result = st
- else:
- st.st_mode = stat.S_IFDIR | 0755
- #st.st_size = 4096
- st.st_nlink = len(self.defaultdirs) + 1
- result = st
- elif len(part) == 2:
- if part[1] == "":
- st.st_mode = stat.S_IFDIR | 0755
- #st.st_size = 4096
- st.st_nlink = len(self.defaultdirs) + 1
- result = st
- elif part[1] == ".bareos-jobinfo":
- st.st_mode = stat.S_IFREG | 0444
- st.st_nlink = 1
- st.st_size = 0
- result = st
- self.logger.debug("Jobs \"%s\": nlink: %s" % (path, str(st.st_nlink)))
- return result
-
- def readdir(self, path, offset):
- splitted = os.path.split(path)
- # copy default dirs
- dirs = list(self.defaultdirs)
- if path == "":
- # TODO: only successful
- data = self.bsock.call("llist jobs")
- #self.logger.debug(data)
- dirs.extend([ str(d['jobid']) for d in data['jobs'] ])
- self.logger.debug("Jobs: \"%s\": %s" % (path, dirs))
- elif splitted[0] == "" or splitted[1] == 0:
- dirs.append( ".bareos-jobinfo" )
- return dirs
-
-
-class FuseCache():
- """
- jobs/
- <jobid>
- """
-
- def __init__(self, bsock):
- self.logger = logging.getLogger()
- self.bsock = bsock
- self.jobs = Jobs(bsock)
- self.path = {
- '': { 'type': TYPE_DIR, 'dirs': [ ".", "..", "jobs" ], 'files': [] },
- }
-
- def get_type(self, path):
- if self.path.has_key(path):
- return self.path[path]['type']
-
- def is_file(self, path):
- return self.get_type(path) == TYPE_FILE
-
- def is_directory(self, path):
- return self.get_type(path) == TYPE_DIR
-
- def exists(self, path):
- return self.path.has_key(path)
-
- def get_nlink(self, path):
- if self.exists(path):
- return len(self.path[path]['dirs'])
- else:
- # TODO: correct?
- return 2
-
- def readdir(self, path, offset):
- entries = None
- if self.path.has_key(path) and self.path[path]['type'] == TYPE_DIR:
- entries = self.path[path]['dirs'] + self.path[path]['files']
- self.logger.debug( "Cache: \"%s\": %s" % (path, entries) )
- return entries
-
-
-class BareosWrapper():
- def __init__(self, bsock):
- self.logger = logging.getLogger()
- self.jobs = Jobs(bsock)
- self.cache = FuseCache(bsock)
-
-
- def getattr(self, path):
-
- # TODO: may cause problems with filenames that ends with "/"
- path = path.rstrip( '/' )
- self.logger.debug( "wrapper: \"%s\"" % (path) )
-
- if path == "/jobs" or path.startswith("/jobs/"):
- st = self.jobs.getattr(path.lstrip("/jobs").lstrip("/"))
- return st
- else:
- st = fuse.Stat()
-
- if self.cache.is_file(path):
- st.st_mode = stat.S_IFREG | 0444
- st.st_nlink = 1
- st.st_size = 0
- return st
- elif self.cache.is_directory(path):
- st.st_mode = stat.S_IFDIR | 0755
- #if 'dirs' in file:
- # st.st_nlink = len(file['dirs'])
- #else:
- st.st_nlink = self.cache.get_nlink(path)
- return st
-
- # TODO: check for existens
- return -errno.ENOENT
-
-
- def readdir(self, path, offset):
- #self.logger.debug( '"' + path + '", offset=' + str(offset) + ')' )
-
- # TODO: may cause problems with filenames that ends with "/"
- path = path.rstrip( '/' )
-
- if path == "/jobs" or path.startswith("/jobs/"):
- entries = self.jobs.readdir(path.lstrip("/jobs").lstrip("/"), offset)
- else:
- entries = self.cache.readdir(path, offset)
-
- self.logger.debug( "wrapper: \"%s\": %s" % (path, pformat(entries)) )
-
- if not entries:
- return -errno.ENOENT
- else:
- return [fuse.Direntry(f) for f in entries]
-
-
-class BareosFuse(fuse.Fuse):
-
- def __init__(self, *args, **kw):
- self.logger = logging.getLogger()
- self.logger.debug('init')
-
- self.bsock = kw['bsockjson']
- if not isinstance(self.bsock,BSockJson):
- raise RuntimeError("parameter bsock")
- del(kw['bsockjson'])
- self.bareos = BareosWrapper(self.bsock)
-
- super(BareosFuse, self).__init__(*args, **kw)
-
-
- def getattr(self, path):
- stat = self.bareos.getattr(path)
- if isinstance(stat, fuse.Stat):
- self.logger.debug("fuse %s: nlink=%i" % (path, stat.st_nlink))
- else:
- self.logger.debug("fuse %s: (int) %i" % (path, stat))
- return stat
-
-
- def readdir(self, path, offset):
- entries = self.bareos.readdir(path, offset)
- self.logger.debug("fuse %s: %s" % (path, entries))
- return entries
-
-
- #def open( self, path, flags ):
- #logging.debug( "open " + path )
- #return -errno.ENOENT
-
- #def read( self, path, length, offset):
- #logging.debug( "read " + path )
- #return -errno.ENOENT
diff --git a/bareos/bsock/bsock.py b/bareos/bsock/bsock.py
index 5795e0e..0466885 100644
--- a/bareos/bsock/bsock.py
+++ b/bareos/bsock/bsock.py
@@ -24,7 +24,7 @@ class BSock(LowLevel):
'''
call a bareos-director user agent command
'''
- self.send(command)
+ self.send(str(command))
return self.recv_msg()
diff --git a/bareos/bsock/lowlevel.py b/bareos/bsock/lowlevel.py
index e100529..e6a83ff 100644
--- a/bareos/bsock/lowlevel.py
+++ b/bareos/bsock/lowlevel.py
@@ -68,9 +68,9 @@ class LowLevel(object):
(ssl, result_compatible, result) = self._cram_md5_respond(password=password.md5(), tls_remote_need=0)
if not result:
- raise AuthenticationError("failed respond")
+ raise AuthenticationError("failed (in response)")
if not self._cram_md5_challenge(clientname=clientname, password=password.md5(), tls_local_need=0, compatible=True):
- raise AuthenticationError("failed challenge")
+ raise AuthenticationError("failed (in challenge)")
return True
diff --git a/bareos/fuse/__init__.py b/bareos/fuse/__init__.py
new file mode 100644
index 0000000..2ef7f37
--- /dev/null
+++ b/bareos/fuse/__init__.py
@@ -0,0 +1,3 @@
+#__all__ = [ "bconsole" ]
+from bareos.fuse.bareosfuse import BareosFuse
+import bareos.fuse.node
diff --git a/bareos/fuse/bareosfuse.py b/bareos/fuse/bareosfuse.py
new file mode 100644
index 0000000..9a2dc60
--- /dev/null
+++ b/bareos/fuse/bareosfuse.py
@@ -0,0 +1,76 @@
+"""
+FUSE filesystem on bareos data.
+"""
+
+from bareos.bsock import BSockJson
+import bareos.bsock
+from bareos.util import Path
+from bareos.fuse.root import Root
+import errno
+import fuse
+import logging
+import stat
+from pprint import pformat
+
+fuse.fuse_python_api = (0, 2)
+
+
+class BareosFuse(fuse.Fuse):
+
+ def __init__(self, *args, **kw):
+ self.logger = logging.getLogger()
+ self.logger.debug('init')
+ self.bsock = None
+ self.bareos = None
+ super(BareosFuse, self).__init__(*args, **kw)
+ self.multithreaded = False
+
+
+ def main(self, *args, **kw):
+ # use main() instead of fsinit,
+ # as this prevents FUSE from being started in case of errors.
+ self.logger.debug('start')
+ if self.fuse_args.mount_expected():
+ options = [ 'address', 'port', 'dirname', 'clientname', 'password' ]
+ parameter = {}
+ for i in options:
+ if hasattr(self, i):
+ self.logger.debug( "%s: %s" %(i, getattr(self,i)))
+ parameter[i] = getattr(self,i)
+ else:
+ self.logger.debug( "%s: missing" %(i))
+ self.logger.debug('options: %s' % (parameter))
+ password = bareos.bsock.Password(self.password)
+ parameter['password']=password
+ self.bsock = bareos.bsock.BSockJson(**parameter)
+ self.bareos = Root(self.bsock)
+ super(BareosFuse, self).main(*args, **kw)
+ self.logger.debug('done')
+
+
+ def getattr(self, path):
+ if self.bareos:
+ stat = self.bareos.getattr(Path(path))
+ if isinstance(stat, fuse.Stat):
+ self.logger.debug("fuse %s: nlink=%i" % (path, stat.st_nlink))
+ else:
+ self.logger.debug("fuse %s: (int) %i" % (path, stat))
+ return stat
+
+
+ def readdir(self, path, offset):
+ entries = self.bareos.readdir(Path(path), offset)
+ self.logger.debug("fuse %s: %s" % (path, entries))
+ if not entries:
+ return -errno.ENOENT
+ else:
+ return [fuse.Direntry(f) for f in entries]
+
+
+ def read(self, path, size, offset):
+ result = self.bareos.read(Path(path), size, offset)
+ #if result == None:
+ # return -errno.ENOENT
+ self.logger.debug("fuse %s: %s" % (path, result))
+ return result
+ #return -errno.ENOENT
diff --git a/bareos/fuse/node/__init__.py b/bareos/fuse/node/__init__.py
new file mode 100644
index 0000000..08588b9
--- /dev/null
+++ b/bareos/fuse/node/__init__.py
@@ -0,0 +1,5 @@
+#__all__ = [ "bconsole" ]
+from bareos.fuse.node.base import Base
+from bareos.fuse.node.file import File
+from bareos.fuse.node.directory import Directory
+from bareos.fuse.node.bareosnodes import *
diff --git a/bareos/fuse/node/bareosnodes.py b/bareos/fuse/node/bareosnodes.py
new file mode 100644
index 0000000..d181772
--- /dev/null
+++ b/bareos/fuse/node/bareosnodes.py
@@ -0,0 +1,169 @@
+"""
+Bareos specific Fuse nodes.
+"""
+
+from bareos.fuse.node import Base
+from bareos.fuse.node import File
+from bareos.fuse.node import Directory
+from dateutil import parser as DateParser
+import errno
+import logging
+from pprint import pformat
+import stat
+
+class Jobs(Directory):
+ def __init__(self, bsock, name):
+ super(Jobs, self).__init__(bsock, name)
+
+ def do_update(self):
+ data = self.bsock.call("llist jobs")
+ jobs = data['jobs']
+ for i in jobs:
+ self.add_subnode(Job(self.bsock, i))
+
+class Job(Directory):
+ def __init__(self, bsock, job):
+ self.job = job
+ super(Job, self).__init__(bsock, self.get_name())
+ try:
+ self.stat.st_ctime = self.convert_date_bareos_unix(self.job['starttime'])
+ except KeyError:
+ pass
+ try:
+ self.stat.st_mtime = self.convert_date_bareos_unix(self.job['realendtime'])
+ except KeyError:
+ pass
+
+ def get_name(self):
+ # TODO: adapt list backups to include name
+ try:
+ name = "jobid={jobid}_client={clientname}_name={name}_level={level}_status={jobstatus}".format(**self.job)
+ except KeyError:
+ name = "jobid={jobid}_level={level}_status={jobstatus}".format(**self.job)
+ return name
+
+ def convert_date_bareos_unix(self, bareosdate):
+ unixtimestamp = int(DateParser.parse(bareosdate).strftime("%s"))
+ self.logger.debug( "unix timestamp: %d" % (unixtimestamp))
+ return unixtimestamp
+
+ 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))
+
+class JobLog(File):
+ def __init__(self, bsock, job):
+ super(JobLog, self).__init__(bsock, "joblog.txt")
+ self.job = job
+ # TODO: static when job is finished
+
+ def do_update(self):
+ jobid = self.job['jobid']
+ data = self.bsock.call( "llist joblog jobid=%s" % (jobid) )
+ self.content = ""
+ for i in data['joblog']:
+ self.content += str(i['time']) + " "
+ self.content += str(i['logtext']) + "\n"
+
+
+class Volumes(Directory):
+ def __init__(self, bsock, name):
+ super(Volumes, self).__init__(bsock, name)
+
+ 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))
+
+class Volume(Directory):
+ def __init__(self, bsock, volume):
+ super(Volume, self).__init__(bsock, volume['volumename'])
+ self.volume = volume
+
+ def do_update(self):
+ self.add_subnode(File(self.bsock, name="info.txt", content = pformat(self.volume) + "\n"))
+
+class Clients(Directory):
+ def __init__(self, bsock, name):
+ super(Clients, self).__init__(bsock, name)
+
+ 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))
+
+class Client(Directory):
+ def __init__(self, bsock, name):
+ super(Client, self).__init__(bsock, name)
+
+ def do_update(self):
+ self.add_subnode(Backups(self.bsock, "backups", client=self.get_name()))
+
+class Backups(Directory):
+ def __init__(self, bsock, name, client):
+ super(Backups, self).__init__(bsock, name)
+ self.client = 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))
+
+class BvfsDir(Directory):
+ def __init__(self, bsock, directory, jobid, pathid):
+ super(BvfsDir, self).__init__(bsock, directory)
+ self.jobid = jobid
+ self.pathid = pathid
+ self.static = True
+
+ def do_update(self):
+ if self.pathid == None:
+ self.bsock.call(".bvfs_update jobid=%s" % (self.jobid))
+ path = "path=/"
+ else:
+ path = "pathid=%s" % self.pathid
+ data = self.bsock.call(".bvfs_lsdirs jobid=%s %s" % (self.jobid, path))
+ directories = data['directories']
+ data = self.bsock.call(".bvfs_lsfiles jobid=%s %s" % (self.jobid, path))
+ files = data['files']
+ for i in directories:
+ if i['name'] != "." and i['name'] != "..":
+ directory = i['name'].rstrip('/')
+ pathid = i['pathid']
+ self.add_subnode(BvfsDir(self.bsock, directory, self.jobid, pathid))
+ for i in files:
+ self.add_subnode(BvfsFile(self.bsock, i))
+
+class BvfsFile(File):
+ def __init__(self, bsock, file):
+ super(BvfsFile, self).__init__(bsock, file['name'], content = None)
+ self.file = file
+ self.static = True
+ self.do_update()
+
+ def do_update(self):
+ self.stat.st_mode = self.file['stat']['mode']
+ self.stat.st_size = self.file['stat']['size']
+ self.stat.st_atime = self.file['stat']['atime']
+ self.stat.st_ctime = self.file['stat']['ctime']
+ self.stat.st_mtime = self.file['stat']['mtime']
+
+ #"stat": {
+ #"atime": 1441134679,
+ #"ino": 3689524,
+ #"dev": 2051,
+ #"mode": 33256,
+ #"nlink": 1,
+ #"user": "joergs",
+ #"group": "joergs",
+ #"ctime": 1441134679,
+ #"rdev": 0,
+ #"size": 1613,
+ #"mtime": 1441134679
+ #},
diff --git a/bareos/fuse/node/base.py b/bareos/fuse/node/base.py
new file mode 100644
index 0000000..afd493f
--- /dev/null
+++ b/bareos/fuse/node/base.py
@@ -0,0 +1,81 @@
+"""
+"""
+
+from datetime import datetime, timedelta
+import errno
+import fuse
+import logging
+import stat
+
+class Base(object):
+ """
+ Base class for filesystem nodes.
+ """
+ def __init__(self, bsock, name):
+ self.logger = logging.getLogger()
+ self.bsock = bsock
+ self.set_name(name)
+ self.stat = fuse.Stat()
+ self.content = None
+ self.subnodes = {}
+ self.static = False
+ self.lastupdate = None
+ # timeout for caching
+ self.cache_timeout = timedelta(seconds=60)
+
+ def get_name(self):
+ return self.name
+
+ def set_name(self, name):
+ self.name = name
+
+ def getattr(self, path):
+ self.logger.debug("%s(\"%s\")" % (str(self), str(path)))
+ result = -errno.ENOENT
+ if path.len() == 0:
+ self.update()
+ result = self.get_stat()
+ else:
+ if path.get(0) in self.subnodes:
+ result = self.subnodes[path.get(0)].getattr(path.lstrip([path.get(0)]))
+ return result
+
+ def get_stat(self):
+ return self.stat
+
+ def read(self, path, size, offset):
+ self.logger.debug("%s(\"%s\", %d, %d)" % (str(self), str(path), size, offset))
+ result = -errno.ENOENT
+ if path.len() == 0:
+ self.logger.debug( "content: " + str(self.content) )
+ self.update()
+ if self.content != None:
+ result = self.content[offset:offset+size]
+ else:
+ if path.get(0) in self.subnodes:
+ result = self.subnodes[path.get(0)].read(path.lstrip([path.get(0)]), size, offset)
+ return result
+
+ def add_subnode(self, obj):
+ name = obj.get_name()
+ if not self.subnodes.has_key(name):
+ self.subnodes[name] = obj
+
+ def update(self):
+ # update status, content, ...
+ now = datetime.now()
+ if self.lastupdate == None:
+ self.logger.debug("reason: first time")
+ self.do_update()
+ self.lastupdate = now
+ 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))
+ self.do_update()
+ self.lastupdate = datetime.now()
+ else:
+ self.logger.debug("skipped")
+
+ def do_update(self):
+ # dummy, to be filled by inherented classes
+ pass
diff --git a/bareos/fuse/node/directory.py b/bareos/fuse/node/directory.py
new file mode 100644
index 0000000..bcd5bb8
--- /dev/null
+++ b/bareos/fuse/node/directory.py
@@ -0,0 +1,36 @@
+"""
+"""
+
+from bareos.fuse.node import Base
+import errno
+import logging
+from pprint import pformat
+import stat
+
+class Directory(Base):
+ """
+ Directory node.
+ """
+ def __init__(self, bsock, name):
+ super(Directory, self).__init__(bsock, name)
+ self.defaultdirs = [ ".", ".." ]
+ self.stat.st_mode = stat.S_IFDIR | 0755
+ self.stat.st_nlink = len(self.defaultdirs)
+ # arbitrary default value
+ self.stat.st_size = 4096
+
+ def readdir(self, path, offset):
+ self.logger.debug("%s(\"%s\")" % (str(self), str(path)))
+ # copy default dirs
+ if path.len() == 0:
+ self.update()
+ # TODO: use encode instead str
+ result = list(self.defaultdirs) + [ str(i) for i in self.subnodes.keys() ]
+ else:
+ if path.get(0) in self.subnodes:
+ result = self.subnodes[path.get(0)].readdir(path.lstrip([path.get(0)]), offset)
+ return result
+
+ def get_stat(self):
+ self.stat.st_nlink = len(self.defaultdirs) + len(self.subnodes)
+ return super(Directory, self).get_stat()
diff --git a/bareos/fuse/node/file.py b/bareos/fuse/node/file.py
new file mode 100644
index 0000000..adb36f7
--- /dev/null
+++ b/bareos/fuse/node/file.py
@@ -0,0 +1,24 @@
+"""
+"""
+
+from bareos.fuse.node import Base
+import errno
+import fuse
+import logging
+from pprint import pformat
+import stat
+
+class File(Base):
+ """
+ File node.
+ """
+ def __init__(self, bsock, name, content = ""):
+ super(File, self).__init__(bsock, name)
+ self.content = content
+ self.stat.st_mode = stat.S_IFREG | 0444
+ self.stat.st_nlink = 1
+
+ def get_stat(self):
+ if self.content != None:
+ self.stat.st_size = len(self.content)
+ return super(File, self).get_stat()
diff --git a/bareos/fuse/root.py b/bareos/fuse/root.py
new file mode 100644
index 0000000..62c1b2c
--- /dev/null
+++ b/bareos/fuse/root.py
@@ -0,0 +1,15 @@
+"""
+"""
+
+from bareos.fuse.node import *
+
+class Root(Directory):
+ """
+ Define filesystem structure of root (/) directory.
+ """
+ def __init__(self, bsock):
+ super(Root, self).__init__(bsock, None)
+ self.add_subnode(Jobs(bsock, "jobs"))
+ self.add_subnode(Volumes(bsock, "volumes"))
+ self.add_subnode(Clients(bsock, "clients"))
+
diff --git a/bareos/util/__init__.py b/bareos/util/__init__.py
index b21b2e0..15c49ce 100644
--- a/bareos/util/__init__.py
+++ b/bareos/util/__init__.py
@@ -1,3 +1,4 @@
#__all__ = [ "bconsole" ]
from bareos.util.bareosbase64 import BareosBase64
from bareos.util.password import Password
+from bareos.util.path import Path \ No newline at end of file
diff --git a/bareos/util/path.py b/bareos/util/path.py
new file mode 100644
index 0000000..8156fba
--- /dev/null
+++ b/bareos/util/path.py
@@ -0,0 +1,84 @@
+"""
+Class to handle Bareos passwords.
+"""
+
+from copy import copy
+
+class Path(object):
+
+ def __init__(self, path=None):
+ self.__set_defaults()
+ self.set_path(path)
+
+ def __str__(self):
+ result = ""
+ if self.is_root():
+ result += "/"
+ result += "/".join(self.path)
+ if (not self.is_root()) or self.len() > 0:
+ if self.is_directory():
+ result += "/"
+ return result
+
+ def __set_defaults(self):
+ self.path_orig = None
+ self.root = False
+ self.directory = False
+ self.path = None
+
+ def set_path(self, path):
+ if path == None:
+ self.__set_defaults()
+ elif isinstance(path, str):
+ self.path_orig = path
+ components = self.path_orig.split('/')
+ self.path = [i for i in components if i != '']
+ if path == "":
+ self.root = False
+ self.directory = True
+ else:
+ self.root = False
+ if self.path_orig[0] == '/':
+ self.root = True
+ self.directory = False
+ if components[-1] == '':
+ self.directory = True
+ else:
+ # exception
+ pass
+
+
+ def get(self, index=None):
+ if index == None:
+ return self.path
+ else:
+ return self.path[index]
+
+
+ def lstrip(self, path=[]):
+ """
+ Creates a new Path instance with lstrip components removed from left.
+ """
+ result = copy(self)
+ result.root = False
+ for i in path:
+ if result.get(0) == i:
+ result.remove(0)
+ else:
+ # TODO: exception?
+ pass
+ return result
+
+
+ def is_directory(self):
+ return self.directory
+
+ def is_root(self):
+ return self.root
+
+
+ def remove(self, index):
+ del(self.path[index])
+
+ def len(self):
+ return len(self.path)
diff --git a/bin/bareos-fuse.py b/bin/bareos-fuse.py
index 37ee52b..bbfc1b6 100755
--- a/bin/bareos-fuse.py
+++ b/bin/bareos-fuse.py
@@ -1,7 +1,7 @@
#!/usr/bin/python
import argparse
-import bareos.bareosfuse
+import bareos.fuse
import bareos.bsock
import fuse
import logging
@@ -9,16 +9,6 @@ import sys
LOG_FILENAME = '/tmp/bareos-fuse-bsock.log'
-#def getArguments():
- #parser = argparse.ArgumentParser(description='Console to Bareos Director.' )
- #parser.add_argument( '-d', '--debug', action='store_true', help="enable debugging output" )
- #parser.add_argument( '-p', '--password', help="password to authenticate at Bareos Director" )
- #parser.add_argument( '--port', default=9101, help="Bareos Director network port" )
- #parser.add_argument( 'address', default="localhost", help="Bareos Director host" )
- #parser.add_argument( 'dirname', nargs='?', default=None, help="Bareos Director name" )
- #args = parser.parse_args()
- #return args
-
if __name__ == '__main__':
# initialize logging
#logging.basicConfig(filename=LOG_FILENAME,level=logging.DEBUG,format="%(asctime)s %(process)5d(%(threadName)s) %(levelname)-7s %(module)s %(funcName)s( %(message)s )")
@@ -28,25 +18,11 @@ if __name__ == '__main__':
logging.basicConfig(filename=LOG_FILENAME,level=logging.DEBUG,format="%(asctime)s %(levelname)-7s %(module)s %(funcName)s( %(message)s )")
logger = logging.getLogger()
- #args=getArguments()
- #if args.debug:
- #logger.setLevel(logging.DEBUG)
-
usage = """
Bareos Fuse filesystem: displays files from Bareos backups as a (userspace) filesystem.
- Internaly, it uses the Bareos bconsole.
""" + fuse.Fuse.fusage
- args = {
- 'address': "localhost",
- 'port': 8001,
- 'password': "RGd7GuCtX+5osHzRoGzJYXkwUpevs2OEMozPOZvbpi4f",
- }
-
- password = bareos.bsock.Password(args['password'])
- director = bareos.bsock.BSockJson(address=args['address'], port=args['port'], password=password)
-
if sys.argv[1] == "--test":
test = bareos.bareosfuse.BareosWrapper(bsock=director)
print test.readdir("", 0)
@@ -56,16 +32,38 @@ if __name__ == '__main__':
print test.readdir("/NOT", 0)
test.getattr("/NOT")
else:
- fs = bareos.bareosfuse.BareosFuse(
+ fs = bareos.fuse.BareosFuse(
#version="%prog: " + BAREOS_FUSE_VERSION,
usage = usage,
# required to let "-s" set single-threaded execution
dash_s_do = 'setsingle',
- bsockjson = director,
)
- #server.parser.add_option(mountopt="root", metavar="PATH", default='/',help="mirror filesystem from under PATH [default: %default]")
- #server.parse(values=server, errex=1)
- fs.parse()
+ fs.parser.add_option(
+ mountopt="address",
+ metavar="BAREOS_DIRECTOR",
+ default='localhost',
+ help="address of the Bareos Director to connect [default: \"%default\"]")
+ fs.parser.add_option(
+ mountopt="port",
+ metavar="PORT",
+ default='9101',
+ help="address of the Bareos Director to connect [default: \"%default\"]")
+ fs.parser.add_option(
+ mountopt="dirname",
+ metavar="NAME",
+ default='',
+ help="name of the Bareos Director to connect [default: \"%default\"]")
+ fs.parser.add_option(
+ mountopt="clientname",
+ metavar="NAME",
+ help="name of the Bareos Named Console")
+ fs.parser.add_option(
+ mountopt="password",
+ metavar="PASSWORD",
+ default='',
+ help="password to authenticate at Bareos Director [default: \"%default\"]")
+
+ fs.parse(values=fs, errex=1)
fs.main()
diff --git a/bin/bconsole-json.py b/bin/bconsole-json.py
index 9ec0acb..fdbcfc0 100755
--- a/bin/bconsole-json.py
+++ b/bin/bconsole-json.py
@@ -7,11 +7,12 @@ import sys
def getArguments():
parser = argparse.ArgumentParser(description='Console to Bareos Director.' )
- parser.add_argument( '-d', '--debug', action='store_true', help="enable debugging output" )
- parser.add_argument( '-p', '--password', help="password to authenticate at Bareos Director" )
- parser.add_argument( '--port', default=9101, help="Bareos Director network port" )
- parser.add_argument( 'address', default="localhost", help="Bareos Director host" )
- parser.add_argument( 'dirname', nargs='?', default=None, help="Bareos Director name" )
+ parser.add_argument('-d', '--debug', action='store_true', help="enable debugging output")
+ parser.add_argument('--name', default="*UserAgent*", help="use this to access a specific Bareos director named console. Otherwise it connects to the default console (\"*UserAgent*\")", dest="clientname")
+ parser.add_argument('-p', '--password', help="password to authenticate to a Bareos Director console", required=True)
+ parser.add_argument('--port', default=9101, help="Bareos Director network port")
+ parser.add_argument('--dirname', help="Bareos Director name")
+ parser.add_argument('address', nargs='?', default="localhost", help="Bareos Director network address")
args = parser.parse_args()
return args
diff --git a/bin/bconsole.py b/bin/bconsole.py
index 54922b9..5b6f703 100755
--- a/bin/bconsole.py
+++ b/bin/bconsole.py
@@ -8,11 +8,12 @@ import sys
def getArguments():
parser = argparse.ArgumentParser(description='Console to Bareos Director.' )
- parser.add_argument( '-d', '--debug', action='store_true', help="enable debugging output" )
- parser.add_argument( '-p', '--password', help="password to authenticate at Bareos Director" )
- parser.add_argument( '--port', default=9101, help="Bareos Director network port" )
- parser.add_argument( 'address', default="localhost", help="Bareos Director host" )
- parser.add_argument( 'dirname', nargs='?', default=None, help="Bareos Director name" )
+ parser.add_argument('-d', '--debug', action='store_true', help="enable debugging output")
+ parser.add_argument('--name', default="*UserAgent*", help="use this to access a specific Bareos director named console. Otherwise it connects to the default console (\"*UserAgent*\")", dest="clientname")
+ parser.add_argument('-p', '--password', help="password to authenticate to a Bareos Director console", required=True)
+ parser.add_argument('--port', default=9101, help="Bareos Director network port")
+ parser.add_argument('--dirname', help="Bareos Director name")
+ parser.add_argument('address', nargs='?', default="localhost", help="Bareos Director network address")
args = parser.parse_args()
return args