def _func(): root = db.get_db().getRoot() now = datetime.datetime.utcnow() f = open(constants.BOOT_UUID, 'rb') uuid = f.read().strip() f.close() root.setS(ns.bootUuid, rdf.String, uuid)
def _open_db(res): _log.debug("WebUiMaster/start(): opening db") if self.is_live_cd() and self.is_lowmem(): _log.info("live cd and lowmem, not starting db connection") self.db = None else: _log.debug("opening database connection") self.db = db.get_db() self.db.open()
def db_flush(dbase=None): """Force RDF database flush.""" if dbase is None: dbase = db.get_db().getModel() @db.untransact(database=dbase) def _dummy(): _log.info('flushing database') _dummy()
def _postops(): model = db.get_db().getModel() root = model.getNodeByUri(ns.l2tpGlobalRoot, rdf.Type(ns.L2tpGlobalRoot)) # attempt to set keymap try: from codebay.l2tpserver import gnomeconfig cfg_ui = root.getS(ns_ui.uiConfig, rdf.Type(ns_ui.UiConfig)) gnomeconfig.set_keymap_settings(cfg_ui.getS(ns_ui.keymap, rdf.String)) except: _log.exception('setting keymap failed in import, ignoring')
def _rdf_database_recover_from_known_good(_log): database_filename = constants.PRODUCT_DATABASE_FILENAME exported_filename = constants.EXPORTED_RDF_DATABASE_FILE res = False if not os.path.exists(exported_filename): _log.info('exported known good file %s does not exist, skipping recover from known good' % exported_filename) return False try: try: from codebay.common import rdf from codebay.l2tpserver import db # remove old database rdf.Database.delete(database_filename) # re-create database, read back from pruned file dbase = rdf.Database.create(database_filename) @db.transact(database=dbase) def _f(): dbase.loadFile(exported_filename) _f() dbase.close() dbase = None # post ops - reset keymap (might have changed, e.g. in recovery) try: from codebay.l2tpserver.rdfconfig import ns, ns_ui from codebay.l2tpserver import gnomeconfig model = db.get_db().getModel() root = model.getNodeByUri(ns.l2tpGlobalRoot, rdf.Type(ns.L2tpGlobalRoot)) cfg_ui = root.getS(ns_ui.uiConfig, rdf.Type(ns_ui.UiConfig)) gnomeconfig.set_keymap_settings(cfg_ui.getS(ns_ui.keymap, rdf.String)) except: _log.exception('setting keymap failed in recovery from known good, ignoring') res = True except: _log.exception('_rdf_database_recover_from_known_good: recovery from known good failed') finally: try: if dbase is not None: dbase.close() dbase = None except: _log.exception('_rdf_database_recover_from_known_good: failed to close hanging db') return res
def create_debug_group(self, form, ctx): debug_group = formalutils.CollapsibleGroup("debug_group", label="Debug") debug_group.setCollapsed(False) debug_group.add( formal.Field( "debug", formal.Integer(required=True, validators=[formal.RangeValidator(min=0, max=2)]), label="Debug mode (0=normal, 1=light, 2=heavy)", ) ) ui_root = db.get_db().getRoot().getS(ns_ui.uiConfig, rdf.Type(ns_ui.UiConfig)) # Default false if no entry found from the database. debug_fda = formalutils.FormDataAccessor(form, ["debug_group"], ctx) if ui_root.hasS(ns_ui.debug): debug_fda["debug"] = ui_root.getS(ns_ui.debug, rdf.Integer) else: debug_fda["debug"] = 0 return debug_group
def create_debug_group(self, form, ctx): debug_group = formalutils.CollapsibleGroup('debug_group', label='Debug') debug_group.setCollapsed(False) debug_group.add( formal.Field('debug', formal.Integer( required=True, validators=[formal.RangeValidator(min=0, max=2)]), label='Debug mode (0=normal, 1=light, 2=heavy)')) ui_root = db.get_db().getRoot().getS(ns_ui.uiConfig, rdf.Type(ns_ui.UiConfig)) # Default false if no entry found from the database. debug_fda = formalutils.FormDataAccessor(form, ['debug_group'], ctx) if ui_root.hasS(ns_ui.debug): debug_fda['debug'] = ui_root.getS(ns_ui.debug, rdf.Integer) else: debug_fda['debug'] = 0 return debug_group
def _rdf_database_stats(): """Log useful statistics about RDF database to syslog.""" try: root = db.get_db().getRoot() model = root.model # XXX: cleaner? count, reachable = model.getPruneStatistics(root) unreachable = count - reachable db_size = os.stat(constants.PRODUCT_DATABASE_FILENAME).st_size # XXX: division by zero is not a real concern, and we're in try-except anyway _log.info('DATABASEINFO: ' \ 'filesize=%.1f MiB (%d), ' \ 'total stmts %d, reachable stmts %d (%.1f%%), unreachable stmts %d (%.1f%%), ' \ 'bytes per reachable stmt avg %.1f, bytes per any stmt avg %.1f' % \ (db_size/(1024.0*1024.0), db_size, count, reachable, float(reachable)/float(count)*100.0, unreachable, float(unreachable)/float(count)*100.0, float(db_size)/float(reachable), float(db_size)/float(count))) except: _log.exception('failed to get rdf database stats')
def _func(): now = datetime.datetime.utcnow() # Global root model = db.get_db().getModel() root = rdf.Node.make(model, rdf.Type(ns.L2tpGlobalRoot), ns.l2tpGlobalRoot) # Global status root global_status = root.setS(ns.globalStatus, rdf.Type(ns.GlobalStatus)) global_status.setS(ns.watchdogReboots, rdf.Integer, 0) global_status.setS(ns.periodicReboots, rdf.Integer, 0) global_status.setS(ns.uncleanRunnerExits, rdf.Integer, 0) retiredpppdevs = global_status.setS(ns.retiredPppDevices, rdf.Type(ns.RetiredPppDevices)) # Update info update_info = root.setS(ns_ui.updateInfo, rdf.Type(ns_ui.UpdateInfo)) update_info.setS(ns_ui.changeLog, rdf.String, '') update_info.setS(ns_ui.latestKnownVersion, rdf.String, '') # License parameters license_info = root.setS(ns_ui.licenseInfo, rdf.Type(ns_ui.LicenseInfo)) license_info.setS(ns_ui.maxNormalConnections, rdf.Integer, 0) license_info.setS(ns_ui.maxSiteToSiteConnections, rdf.Integer, 0) license_info.setS(ns_ui.validityStart, rdf.Datetime, now) license_info.setS(ns_ui.validityEnd, rdf.Datetime, now) license_info.setS(ns_ui.validityRecheckLatest, rdf.Datetime, now) license_info.setS(ns_ui.licenseString, rdf.String, '') license_info.setS(ns_ui.isDemoLicense, rdf.Boolean, False) license_info.setS(ns_ui.demoValidityStart, rdf.Datetime, now) license_info.setS(ns_ui.demoValidityEnd, rdf.Datetime, now) # XXX: what other roots should we add here? f = open(constants.INSTALLATION_UUID, 'rb') uuid = f.read().strip() f.close() root.setS(ns.installationUuid, rdf.String, uuid)
def _doimport(): # Read the import. Prune at the end, just in case. _log.info('configuration import: getting model') model = db.get_db().getModel() _log.info('configuration import: loading import file %s' % import_file) model.loadFile(import_file) _log.info('configuration import: in-place prune') root = model.getNodeByUri(ns.l2tpGlobalRoot, rdf.Type(ns.L2tpGlobalRoot)) model.prune(root) _log.info('configuration import: prune ok') # fix configuration version differences # # Missing values do not have to be fixed here if defaults are ok; # caller will use fix_missing_database_values() to set defaults # for all missing values. Caller will also regenerate protocol # configuration so that doesn't have to be done here either. # reset installation UUID to current system _log.info('configuration import: setting installation uuid') f = open(constants.INSTALLATION_UUID, 'rb') uuid = f.read().strip() f.close() root.setS(ns.installationUuid, rdf.String, uuid)
def get_license_info(): """Get license information node from RDF database.""" return db.get_db().getRoot().getS(ns_ui.licenseInfo, rdf.Type(ns_ui.LicenseInfo))
def get_new_ui_config(): """Get new UI config node from RDF database.""" return db.get_db().getRoot().getS(ns_ui.newUiConfig, rdf.Type(ns_ui.UiConfig))
def get_global_status(): """Get global status root node from RDF database.""" return db.get_db().getRoot().getS(ns.globalStatus, rdf.Type(ns.GlobalStatus))
def get_status(): """Get protocol status root node from RDF database.""" return db.get_db().getRoot().getS(ns.l2tpDeviceStatus, rdf.Type(ns.L2tpDeviceStatus))
def get_db_root(): return db.get_db().getRoot()
def save_debug(self, ctx, form, data): ui_root = db.get_db().getRoot().getS(ns_ui.uiConfig, rdf.Type(ns_ui.UiConfig)) debug_fda = formalutils.FormDataAccessor(form, ['debug_group'], ctx) ui_root.setS(ns_ui.debug, rdf.Integer, debug_fda['debug'])
def render_dump(self, ctx, data): rd = rdfdumper.RdfDumper() return rd.dump_resource(db.get_db().getRoot())
def save_debug(self, ctx, form, data): ui_root = db.get_db().getRoot().getS(ns_ui.uiConfig, rdf.Type(ns_ui.UiConfig)) debug_fda = formalutils.FormDataAccessor(form, ["debug_group"], ctx) ui_root.setS(ns_ui.debug, rdf.Integer, debug_fda["debug"])
def _rdf_database_create_initial(_log): """Create empty config root. This function is called when our current configuration is missing or broken. The initialized configuration has the proper structure (contains the mandatory nodes which pass sanity check) but is otherwise empty. XXX: We should probably add some warning or cause as to why the configuration is empty. """ dbase = None try: try: from codebay.common import rdf from codebay.l2tpserver.rdfconfig import ns, ns_ui from codebay.l2tpserver.webui import uidatahelpers from codebay.l2tpserver import db # close database if open; just sanity try: db.get_db().close() except: _log.exception('failed to close database before recreating, ignoring') # remove old database rdf.Database.delete(constants.PRODUCT_DATABASE_FILENAME) # create new one dbase = rdf.Database.create(constants.PRODUCT_DATABASE_FILENAME) dbase.close() dbase = None @db.transact() def _func(): now = datetime.datetime.utcnow() # Global root model = db.get_db().getModel() root = rdf.Node.make(model, rdf.Type(ns.L2tpGlobalRoot), ns.l2tpGlobalRoot) # Global status root global_status = root.setS(ns.globalStatus, rdf.Type(ns.GlobalStatus)) global_status.setS(ns.watchdogReboots, rdf.Integer, 0) global_status.setS(ns.periodicReboots, rdf.Integer, 0) global_status.setS(ns.uncleanRunnerExits, rdf.Integer, 0) retiredpppdevs = global_status.setS(ns.retiredPppDevices, rdf.Type(ns.RetiredPppDevices)) # Update info update_info = root.setS(ns_ui.updateInfo, rdf.Type(ns_ui.UpdateInfo)) update_info.setS(ns_ui.changeLog, rdf.String, '') update_info.setS(ns_ui.latestKnownVersion, rdf.String, '') # License parameters license_info = root.setS(ns_ui.licenseInfo, rdf.Type(ns_ui.LicenseInfo)) license_info.setS(ns_ui.maxNormalConnections, rdf.Integer, 0) license_info.setS(ns_ui.maxSiteToSiteConnections, rdf.Integer, 0) license_info.setS(ns_ui.validityStart, rdf.Datetime, now) license_info.setS(ns_ui.validityEnd, rdf.Datetime, now) license_info.setS(ns_ui.validityRecheckLatest, rdf.Datetime, now) license_info.setS(ns_ui.licenseString, rdf.String, '') license_info.setS(ns_ui.isDemoLicense, rdf.Boolean, False) license_info.setS(ns_ui.demoValidityStart, rdf.Datetime, now) license_info.setS(ns_ui.demoValidityEnd, rdf.Datetime, now) # XXX: what other roots should we add here? f = open(constants.INSTALLATION_UUID, 'rb') uuid = f.read().strip() f.close() root.setS(ns.installationUuid, rdf.String, uuid) _func() # UI default database (also creates initial protocol config) # (separate transaction) @db.transact() def _func(): uidatahelpers.create_default_database() _func() except: _log.exception('_rdf_database_create_initial failed, fatal') finally: try: # this is just for sanity if dbase is not None: dbase.close() dbase = None except: _log.exception('_rdf_database_create_initial, failed to close db') return None
def _close_db(): try: from codebay.l2tpserver import db db.get_db().close() except: _log.exception('failed to close l2tpserver db')
def _check_configuration_import(_log): from codebay.l2tpserver import db from codebay.common import rdf from codebay.l2tpserver.rdfconfig import ns, ns_ui import_file = constants.CONFIGURATION_IMPORT_BOOT_FILE if os.path.exists(import_file): _log.info('configuration import file exists (%s), attempting import' % import_file) def _nukeold(): # Nuke old database _log.info('configuration import: creating a fresh database') db.get_db().close() db.get_db().create() @db.transact() def _doimport(): # Read the import. Prune at the end, just in case. _log.info('configuration import: getting model') model = db.get_db().getModel() _log.info('configuration import: loading import file %s' % import_file) model.loadFile(import_file) _log.info('configuration import: in-place prune') root = model.getNodeByUri(ns.l2tpGlobalRoot, rdf.Type(ns.L2tpGlobalRoot)) model.prune(root) _log.info('configuration import: prune ok') # fix configuration version differences # # Missing values do not have to be fixed here if defaults are ok; # caller will use fix_missing_database_values() to set defaults # for all missing values. Caller will also regenerate protocol # configuration so that doesn't have to be done here either. # reset installation UUID to current system _log.info('configuration import: setting installation uuid') f = open(constants.INSTALLATION_UUID, 'rb') uuid = f.read().strip() f.close() root.setS(ns.installationUuid, rdf.String, uuid) @db.transact() def _postops(): model = db.get_db().getModel() root = model.getNodeByUri(ns.l2tpGlobalRoot, rdf.Type(ns.L2tpGlobalRoot)) # attempt to set keymap try: from codebay.l2tpserver import gnomeconfig cfg_ui = root.getS(ns_ui.uiConfig, rdf.Type(ns_ui.UiConfig)) gnomeconfig.set_keymap_settings(cfg_ui.getS(ns_ui.keymap, rdf.String)) except: _log.exception('setting keymap failed in import, ignoring') # XXX: root password is not in configuration, so we cannot import it. # This is probably best, so we cannot do anything about it here. try: _nukeold() _doimport() _postops() # done _log.info('configuration import: all done') except: # XXX: show import failure somehow to user after boot _log.exception('configuration import failed') try: # close db just in case db.get_db().close() except: _log.exception('db close failed, ignoring') # unlink even if failed, file is probably corrupt _log.info('deleting import file %s' % import_file) os.unlink(import_file) _log.info('deleting of import file successful') else: _log.debug('no import file')
def render_dump(self, ctx, data): rd = rdfdumper.RdfDumper() return rd.dump_resource(db.get_db().getRoot().getS( ns.l2tpDeviceStatus))
res.append(t) # render string arcs for [p,o] in stringarcs: res.append(ind2 + '%s = "%s" (%s)' % (self._prettify_uri(p.getUri()), o.getLiteral(), self._prettify_uri(o.getDatatype()))) # render rdf number _n arcs, regardless of type for [n,p,o] in numberedarcs: if o.isLiteral(): res.append(ind2 + '%s = "%s" (%s)' % (self._prettify_uri(p.getUri()), o.getLiteral(), self._prettify_uri(o.getDatatype()))) else: res.append(ind2 + self._prettify_uri(p.getUri())) res.extend(self._dump(o, indent+2)) # render resource arcs (blank or otherwise) for [p,o] in resourcearcs: res.append(ind2 + self._prettify_uri(p.getUri())) res.extend(self._dump(o, indent+2)) # loop detection del self._visiting[unicode(node.getUri())] return res if __name__ == '__main__': from codebay.l2tpserver import db rd = RdfDumper() print rd.dump_resource(db.get_db().getRoot())
def render_dump(self, ctx, data): rd = rdfdumper.RdfDumper() return rd.dump_resource(db.get_db().getRoot().getS(ns.l2tpDeviceStatus))
def get_new_config(): """Get new protocol configuration root node from RDF database.""" return db.get_db().getRoot().getS(ns.newL2tpDeviceConfig, rdf.Type(ns.L2tpDeviceConfig))
def _nukeold(): # Nuke old database _log.info('configuration import: creating a fresh database') db.get_db().close() db.get_db().create()
def _do_runner(self): """Handle runner command line commands.""" if len(sys.argv) == 1: self.usage_and_exit() cmd = sys.argv[1] opt = optparse.OptionParser(usage='%prog', version='%prog') opt.add_option('-r', '--rdf-file', help='RDF file instead of default database', action='store', dest='rdf_file', type='string', metavar='<file>') opt.add_option('-m', '--mode', help='Mode for start', action='store', dest='mode', type='string', metavar='<string>') opt.add_option('-i', '--import-path', dest='importpath') opt.add_option('-n', '--no-distro-restart', help='Prevent distro networking restart on runner stop', action='store_true', dest='no_distro_restart', default=False) opt.set_defaults(rdf_file=None, mode=None, importpath='system') (opts, args) = opt.parse_args(sys.argv[2:]) print 'Command = %s, Options: %s' % (cmd, str(opts)) if opts.rdf_file is not None: print 'runner using database file: %s' % opts.rdf_file db.replace_database_with_file(opts.rdf_file, constants.RUNNER_TEMPORARY_SQLITE_DATABASE) if opts.mode is not None: mode = opts.mode else: mode = 'FULL' print 'no mode given, using %s' % mode importpath = 'system' if opts.importpath is not None: importpath = opts.importpath nodistrorestart = False if opts.no_distro_restart is not None and opts.no_distro_restart: nodistrorestart = True # XXX: these need rethinking, currently ripped from startstop.py. # XXX: this should probably be some command name => lambda system, to make command help etc easier # XXX: also need transactions here to make things reasonably fast (e.g. for rdf dumps) try: if mode == 'FULL': runner_mode = startstop._mode_full elif mode == 'NETWORK-ONLY': runner_mode = startstop._mode_network_only else: raise Exception('unknown mode: %s' % mode) _log.debug('starting runner in mode: %s' % runner_mode) r = startstop.L2tpRunner(mode=runner_mode, nodistrorestart=nodistrorestart, importpath=importpath) if cmd == 'run': r.create_pidfile() r.run() elif cmd == 'resetstate': # Set to a fresh node - this orphans all previous state return db.get_db().getRoot().setS(ns.l2tpDeviceStatus, rdf.Type(ns.L2tpDeviceStatus)) elif cmd == 'dumpall': rd = rdfdumper.RdfDumper() print rd.dump_resource(db.get_db().getRoot(), escaped=True) elif cmd == 'dumpstatus': rd = rdfdumper.RdfDumper() print rd.dump_resource(db.get_db().getRoot().getS(ns.l2tpDeviceStatus), escaped=True) elif cmd == 'dumpconfig': rd = rdfdumper.RdfDumper() print rd.dump_resource(db.get_db().getRoot().getS(ns.l2tpDeviceConfig), escaped=True) elif cmd == 'status': st_root = helpers.get_status() st_last_str = 'unknown' if st_root.hasS(ns.lastStateUpdate): st_last_str = st_root.getS(ns.lastStateUpdate, rdf.Datetime).isoformat() st_start_str = 'unknown' if st_root.hasS(ns.startTime): st_start_str = st_root.getS(ns.startTime, rdf.Datetime).isoformat() st_stop_str = 'unknown' if st_root.hasS(ns.stopTime): st_stop_str = st_root.getS(ns.stopTime, rdf.Datetime).isoformat() st_str = 'unknown' st = st_root.getS(ns.state) if st.hasType(ns.StateStarting): st_str = 'starting' subst = st.getS(ns.subState) if subst.hasType(ns.StateStartingPreparing): st_str += ' - preparing' if subst.hasType(ns.StateStartingWaitingForDhcp): st_str += ' - waiting for dhcp' if subst.hasType(ns.StateStartingNetwork): st_str += ' - starting network' if subst.hasType(ns.StateStartingDaemons): st_str += ' - starting daemons' elif st.hasType(ns.StateRunning): st_str = 'running' elif st.hasType(ns.StateStopping): st_str = 'stopping' elif st.hasType(ns.StateStopped): st_str = 'stopped' st_ppp = 'unknown' if st_root.hasS(ns.pppDevices): st_ppp = '%s' % len(helpers.get_ppp_devices()) print 'STATUS: start=%s, stop=%s, last_update=%s, devs=%s, state: %s' % (st_start_str, st_stop_str, st_last_str, st_ppp, st_str) elif cmd == 'start': r.start() elif cmd == 'public-interface-test': # XXX pass elif cmd == 'private-interface-test': # XXX pass elif cmd == 'route-test': # XXX pass elif cmd == 'stop': r.stop() else: raise Exception('unknown command: %s' % cmd) except: _log.exception('l2tpgw-runner command "%s" failed.' % cmd) raise