def test_get_upcoming_jobs(self): b = BConsole() with patch.object(b, 'start_process') as mock_method: start_process = mock_method.return_value start_process.communicate.return_value = (""" Scheduled Jobs: Level Type Pri Scheduled Name Volume =================================================================================== Differential Backup 10 18-Mar-12 23:05 BackupClient1 *unknown* Full Backup 11 18-Mar-12 23:10 BackupCatalog *unknown* ==== """, '') jobs = b.get_upcoming_jobs() self.assertEqual(jobs, [{'date': '18-Mar-12', 'level': 'Differential', 'name': 'BackupClient1', 'priority': '10', 'time': '23:05', 'type': 'Backup', 'volume': '*unknown*'}, {'date': '18-Mar-12', 'level': 'Full', 'name': 'BackupCatalog', 'priority': '11', 'time': '23:10', 'type': 'Backup', 'volume': '*unknown*'}])
def modify_storage(request): bc = BConsole() enderer='templates/storage_list.jinja2', storages = ['File',] log.debug('###################################') log.debug(request.params) log.debug('###################################') command = request.POST.get('command') if command == 'unmount': ret = {'okmsg':'Storage unmounted correctly'} for storage in storages: if not bc.unmount_storage(storage): msg = 'Error unmounting storage: %s' % storage log.info(msg) ret = {'errormsg':msg} break else: ret = {'okmsg':'Storage mounted correctly'} for storage in storages: if not bc.mount_storage(storage): msg = 'Error mounting storage: %s' % storage log.info(msg) ret = {'errormsg':msg} break redirect_url = request.route_url('storage_list', _query=ret) response = HTTPFound(location=redirect_url) return response
def test_get_upcoming_jobs(self): b = BConsole() with patch.object(b, 'start_process') as mock_method: start_process = mock_method.return_value start_process.communicate.return_value = (""" Scheduled Jobs: Level Type Pri Scheduled Name Volume =================================================================================== Incremental Backup 10 07-aoû2013 00:12 srv-prdadm-21_BOS DISK_sem-0004 Admin 8 18-Apr-12 20:30 UpdateSlots Differential Backup 10 18-Mar-12 23:05 BackupClient1 *unknown* Full Backup 11 18-Mar-12 23:10 BackupCatalog *unknown* ==== """, '') jobs = b.get_upcoming_jobs() self.assertEqual(str(jobs).decode('utf-8'), u"[{'volume': 'DISK_sem-0004', 'name':" " 'srv-prdadm-21_BOS', 'level': 'Incremental'," " 'priority': '10', 'time': '00:12', 'date':" " '07-ao\\xc3\\xbb2013', 'type': 'Backup'}," " {'priority': '18-Apr-12', 'date': '20:30'," " 'time': 'UpdateSlots', 'type': '8', 'level': 'Admin'}," " {'volume': '*unknown*', 'name': 'BackupClient1'," " 'level': 'Differential', 'priority': '10', " "'time': '23:05', 'date': '18-Mar-12', 'type': 'Backup'}," " {'volume': '*unknown*', 'name': 'BackupCatalog', " "'level': 'Full', 'priority': '11', 'time': '23:10'," " 'date': '18-Mar-12', 'type': 'Backup'}]")
def test_get_disabled_jobs(self): b = BConsole() with patch.object(b, 'start_process') as mock_method: start_process = mock_method.return_value start_process.communicate.return_value = ("""Disabled Jobs: Backupclient1 """, '') jobs = b.get_disabled_jobs() self.assertEqual(jobs, [{'name': 'Backupclient1'}])
def test_is_running(self): b = BConsole() with patch.object(b, 'start_process') as mock_method: start_process = mock_method.return_value start_process.communicate.return_value = ('Version', '') self.assertTrue(b.is_running()) with patch.object(b, 'start_process') as mock_method: start_process = mock_method.return_value start_process.communicate.return_value = ('error', 'error') self.assertFalse(b.is_running())
def test_unmount_storage(self): b = BConsole() with patch.object(b, 'start_process') as mock_method: start_process = mock_method.return_value start_process.communicate.return_value = ('unmounted.', '') self.assertTrue(b.unmount_storage('File')) with patch.object(b, 'start_process') as mock_method: start_process = mock_method.return_value start_process.communicate.return_value = ('error', 'error') self.assertFalse(b.unmount_storage('File'))
def test_enable_job(self): b = BConsole() with patch.object(b, 'start_process') as mock_method: start_process = mock_method.return_value start_process.communicate.return_value = ('enabled', '') self.assertTrue(b.enable_job('testjob')) with patch.object(b, 'start_process') as mock_method: start_process = mock_method.return_value start_process.communicate.return_value = ('error', 'error') self.assertFalse(b.enable_job('testjob'))
def test_estimate_job(self): b = BConsole() with patch.object(b, 'start_process') as mock_method: start_process = mock_method.return_value start_process.communicate.return_value = ("2000 OK estimate files=1000 bytes=10,000,000", '') self.assertTrue(b.estimate_job('testjob')==(1000,10000000)) with patch.object(b, 'start_process') as mock_method: start_process = mock_method.return_value start_process.communicate.return_value = ('error', 'error') self.assertTrue(b.estimate_job('testjob')==(-1,-1))
def test_get_upcoming_jobs(self): b = BConsole() with patch.object(b, 'start_process') as mock_method: start_process = mock_method.return_value start_process.communicate.return_value = (""" Scheduled Jobs: Level Type Pri Scheduled Name Volume =================================================================================== Incremental Backup 10 07-aoû2013 00:12 srv-prdadm-21_BOS DISK_sem-0004 Admin 8 18-Apr-12 20:30 UpdateSlots Differential Backup 10 18-Mar-12 23:05 BackupClient1 *unknown* Full Backup 11 18-Mar-12 23:10 BackupCatalog *unknown* ==== """, '') jobs = b.get_upcoming_jobs() self.assertEqual(jobs, [{ 'date': '07-aoû2013', 'level': 'Incremental', 'name': 'srv-prdadm-21_BOS', 'time': '00:12', 'priority': '10', 'type': 'Backup', 'volume': 'DISK_sem-0004' }, { 'date': '18-Apr-12', 'level': '', 'name': 'UpdateSlots', 'time': '20:30', 'priority': '8', 'type': 'Admin', 'volume': '' }, { 'date': '18-Mar-12', 'level': 'Differential', 'name': 'BackupClient1', 'priority': '10', 'time': '23:05', 'type': 'Backup', 'volume': '*unknown*' }, { 'date': '18-Mar-12', 'level': 'Full', 'name': 'BackupCatalog', 'priority': '11', 'time': '23:10', 'type': 'Backup', 'volume': '*unknown*' }])
def test_send_command_by_polling(self): b = BConsole() with patch.object(b, 'start_process') as mock_method: mock_method.return_value = Popen(['cat'], stdout=PIPE, stdin=PIPE, stderr=PIPE) process, outputs = b.send_command_by_polling('version') self.assertEqual(outputs['commands'][0], 'version<br />') process.kill() time.sleep(1) process, outputs = b.send_command_by_polling('version', process) self.assertTrue('error' in outputs) with patch.object(b, 'start_process') as mock_method: start_process = mock_method.return_value start_process.communicate.return_value = ('error', 'error') process, outputs = b.send_command_by_polling('quit') self.assertEqual(outputs['commands'][0], 'Try harder.')
def ajax_console_input(request): global bconsole_session # TODO: if status for client is requested, it might timeout after few seconds, but not 0.5 # TODO: thread locking # TODO: implement session based on cookie # TODO: stderr? if not request.POST['bconsole_command'] and bconsole_session is not None: return {"commands": list(command_cache)} b = BConsole() bconsole_session, response = b.send_command_by_polling(request.POST['bconsole_command'], bconsole_session) if 'error' in response: command_cache.clear() if 'commands' in response: command_cache.extend(response['commands']) return response
def get_list(cls, **kw): appstruct = kw.get('appstruct', {}) if appstruct and appstruct['state'] == 'scheduled': return BConsole().get_upcoming_jobs() query = cls.query.options(joinedload(cls.status), joinedload(cls.client)) if appstruct: if appstruct['status']: query = query.filter(cls.jobstatus == appstruct['status']) if appstruct['type']: query = query.filter(cls.type == appstruct['type']) return query
def test_create_label(self): b = BConsole() with patch.object(b, 'start_process') as mock_method: start_process = mock_method.return_value start_process.communicate.return_value = ('successfully created', '') self.assertTrue(b.create_label(pool='test', label = 'testlabel')) with patch.object(b, 'start_process') as mock_method: start_process = mock_method.return_value start_process.communicate.return_value = ('successfully created', '') self.assertTrue(b.create_label(pool= 'test' , storage='test', label = 'testlabel')) with patch.object(b, 'start_process') as mock_method: start_process = mock_method.return_value start_process.communicate.return_value = ('successfully created', '') self.assertTrue(b.create_label(pool='test', label = 'testlabel' )) with patch.object(b, 'start_process') as mock_method: start_process = mock_method.return_value start_process.communicate.return_value = ('successfully created', '') self.assertTrue(b.create_label(pool='test', barcode = True))
def test_delete(self): b = BConsole() with patch.object(b, 'start_process') as mock_method: start_process = mock_method.return_value start_process.communicate.return_value = ('deleted', '') self.assertTrue(b.delete(volume='test')) with patch.object(b, 'start_process') as mock_method: start_process = mock_method.return_value start_process.communicate.return_value = ('deleted', '') self.assertTrue(b.delete(jobid=1)) with patch.object(b, 'start_process') as mock_method: start_process = mock_method.return_value start_process.communicate.return_value = ('error', 'error') self.assertFalse(b.delete(volume='test')) with patch.object(b, 'start_process') as mock_method: start_process = mock_method.return_value start_process.communicate.return_value = ('error', 'error') self.assertFalse(b.delete(jobid=1))
def test_from_temp_config(self): output = \ """# generated by almir, you should never edit this file. Do: # vim buildout.cfg # bin/buildout # bin/supervisorctl restart all Director { Name = test DIRport = 12345 address = add Password = "******" } """ with BConsole.from_temp_config(name='test', address='add', port='12345', password='******') as b: expected = open(b.config_file).read() self.assertEqual( expected.replace(' ', '').replace('\r', ''), output.replace(' ', '').replace('\r', ''))
def test_from_temp_config(self): output = \ """# generated by almir, you should never edit this file. Do: # vim buildout.cfg # bin/buildout # bin/supervisorctl restart all Director { Name = test DIRport = 12345 address = add Password = "******" } """ with BConsole.from_temp_config( name='test', address='add', port='12345', password='******' ) as b: expected = open(b.config_file).read() self.assertEqual(expected.replace(' ', ''), output.replace(' ', ''))
def main(): """Entry point of this script""" print '\n\nConfiguring almir ... If you want to use the default value (where possible), press enter.\n' options = {} options['host'] = ask_question('Host to listen on (default: 127.0.0.1): ', default='127.0.0.1') options['port'] = ask_question('Port to listen on (default: 2500): ', default='2500', validator=validate_open_port) print 'Define SQL database connection to bacula catalog as specified in http://docs.sqlalchemy.org/en/latest/core/engines.html#database-urls' print 'For example:' print ' postgresql+pg8000://<user>:<password>@<hostname>/<database>' print ' mysql+mysqlconnector://<user>:<password>@<hostname>/<database>' print ' sqlite:////var/lib/bacula/bacula.db' print ' sqlite:///bacula.db' print options['engine'] = ask_question('SQL connection string: ', validator=validate_engine) print 'Timezone of director in format of TZ* column in table https://en.wikipedia.org/wiki/List_of_tz_database_time_zones' print 'For example:' print ' Europe/Ljubljana' print ' CET' print try: default_timezone = " (default: %s)" % pytz.timezone(time.tzname[0]) except: default_timezone = '' options['timezone'] = ask_question('Timezone%s' % default_timezone, default='', validator=validate_timezone) # TODO: in future we may extract this from bconsole config file? print 'Almost finished, we just need bconsole parameters to connect to director!' print 'Normally you will find needed information in /etc/bacula/bconsole.conf' print try: output = subprocess.Popen(['which', 'bconsole'], stdout=subprocess.PIPE).communicate()[0].strip() except subprocess.CalledProcessError: print 'WARNING: bconsole command is not executable from current user!' else: if not os.access(output, os.X_OK): print 'WARNING: bconsole command is not executable from current user!' bconsole_running = False while not bconsole_running: options['director_name'] = ask_question('Name of director to connect to (default: localhost-dir): ', default='localhost-dir') options['director_address'] = ask_question('Address of director to connect to (default: localhost): ', default='localhost') options['director_port'] = ask_question('Port of director to connect to (default: 9101): ', default='9101', validator=validate_open_port) options['director_password'] = ask_question('Password of director to connect to: ', func=getpass.getpass) print 'Connecting director with bconsole to verify configuration ...' # need a way to generate bconsole config before running this with BConsole.from_temp_config(name=options['director_name'], address=options['director_address'], port=options['director_port'], password=options['director_password']) as bconsole: if bconsole.is_running(): print 'OK!' bconsole_running = True else: print 'ERROR: Could not connect to director %s, verify configuration and try again!' % options['director_name'] # PRAGMA: no cover with open(OUTPUT, 'w') as f: f.write(TEMPLATE % options) print print 'Written to %s.' % os.path.realpath(OUTPUT)
def get_upcoming(cls): return BConsole().get_upcoming_jobs()
def main(): """Entry point of this script""" print '\n\nConfiguring almir ... If you want to use the default value (where possible), press enter.\n' options = {} options['host'] = ask_question('Host to listen on (default: 127.0.0.1): ', default='127.0.0.1') options['port'] = ask_question('Port to listen on (default: 2500): ', default='2500', validator=validate_open_port) print 'Define SQL database connection to bacula catalog as specified in http://docs.sqlalchemy.org/en/latest/core/engines.html#database-urls' print 'For example:' print ' postgresql+pg8000://<user>:<password>@<hostname>/<database>' print ' mysql+mysqlconnector://<user>:<password>@<hostname>/<database>' print ' sqlite:////var/lib/bacula/bacula.db' print ' sqlite:///bacula.db' print options['engine'] = ask_question('SQL connection string: ', validator=validate_engine) print 'Timezone of director in format of TZ* column in table https://en.wikipedia.org/wiki/List_of_tz_database_time_zones' print 'For example:' print ' Europe/Ljubljana' print ' CET' print try: default_timezone = " (default: %s)" % pytz.timezone(time.tzname[0]) except: default_timezone = '' options['timezone'] = ask_question('Timezone%s' % default_timezone, default='', validator=validate_timezone) # TODO: in future we may extract this from bconsole config file? print 'Almost finished, we just need bconsole parameters to connect to director!' print 'Normally you will find needed information in /etc/bacula/bconsole.conf' print try: output = subprocess.Popen( ['which', 'bconsole'], stdout=subprocess.PIPE).communicate()[0].strip() except subprocess.CalledProcessError: print 'WARNING: bconsole command is not executable from current user!' else: if not os.access(output, os.X_OK): print 'WARNING: bconsole command is not executable from current user!' bconsole_running = False while not bconsole_running: options['director_name'] = ask_question( 'Name of director to connect to (default: localhost-dir): ', default='localhost-dir') options['director_address'] = ask_question( 'Address of director to connect to (default: localhost): ', default='localhost') options['director_port'] = ask_question( 'Port of director to connect to (default: 9101): ', default='9101', validator=validate_open_port) options['director_password'] = ask_question( 'Password of director to connect to: ', func=getpass.getpass) print 'Connecting director with bconsole to verify configuration ...' # need a way to generate bconsole config before running this with BConsole.from_temp_config( name=options['director_name'], address=options['director_address'], port=options['director_port'], password=options['director_password']) as bconsole: if bconsole.is_running(): print 'OK!' bconsole_running = True else: print 'ERROR: Could not connect to director %s, verify configuration and try again!' % options[ 'director_name'] # PRAGMA: no cover with open(OUTPUT, 'w') as f: f.write(TEMPLATE % options) print print 'Written to %s.' % os.path.realpath(OUTPUT)
def dashboard(request): dbsession = DBSession() jobs = Job.get_last() running_jobs = Job.get_running() upcoming_jobs = Job.get_upcoming() try: director_version = '<span title="Connected to" class="label label-success">%s</span>' % BConsole().get_version() except DirectorNotRunning: director_version = '<span class="label label-important">Director not running!</span>' # statistics num_clients = dbsession.query(count(Client.clientid)).scalar() num_jobs = dbsession.query(count(Job.jobid)).scalar() num_volumes = dbsession.query(count(Media.mediaid)).scalar() sum_volumes = Media.format_byte_size(dbsession.query(sum(Media.volbytes)).scalar() or 0) database_size = get_database_size(DBSession.bind) return locals()