def init_db(metadata): logger.info('Creating tables in empty database') if metadata != tg_metadata: metadata.tables = tg_metadata.tables.copy() metadata.create_all() logger.info('Stamping database with Alembic "head" revision') def stamp(rev, context): try: return context.script._stamp_revs('head', rev) except AttributeError: # alembic < 0.7 current = context._current_rev() head = context.script.get_revision('head') context._update_current_rev(current, head.revision) return [] run_alembic_operation(metadata, stamp) # Also mark all data migrations as done, because there is no data to # migrate. This avoids beakerd wasting time trying to run them all when it # first starts up. session = create_session(bind=metadata.bind) with session.begin(): for migration_name in DataMigration.all_names(): logger.info('Marking data migration %s finished', migration_name) session.add(DataMigration(name=migration_name, finish_time=datetime.datetime.utcnow()))
def schedule(): global running global _outstanding_data_migrations _outstanding_data_migrations = [ m for m in DataMigration.all() if not m.is_finished ] if _outstanding_data_migrations: log.debug('Incomplete data migrations will be run: %s', ', '.join(m.name for m in _outstanding_data_migrations)) interface.start(config) if config.get('carbon.address'): log.debug('starting metrics thread') metrics_thread = threading.Thread(target=metrics_loop, name='metrics') metrics_thread.daemon = True metrics_thread.start() beakerd_threads = set(["main_recipes"]) log.debug("starting main recipes thread") main_recipes_thread = threading.Thread(target=main_recipes_loop, name="main_recipes") main_recipes_thread.daemon = True main_recipes_thread.start() try: while True: time.sleep(20) running_threads = set([t.name for t in threading.enumerate()]) if not running_threads.issuperset(beakerd_threads): log.critical("a thread has died, shutting down") rc = 1 running = False event.set() break event.set() event.clear() except (SystemExit, KeyboardInterrupt): log.info("shutting down") running = False event.set() rc = 0 if _threadpool_executor: _threadpool_executor.shutdown() interface.stop() main_recipes_thread.join(10) sys.exit(rc)
def schedule(): global running global _outstanding_data_migrations _outstanding_data_migrations = [m for m in DataMigration.all() if not m.is_finished] if _outstanding_data_migrations: log.debug('Incomplete data migrations will be run: %s', ', '.join(m.name for m in _outstanding_data_migrations)) interface.start(config) if config.get('carbon.address'): log.debug('starting metrics thread') metrics_thread = threading.Thread(target=metrics_loop, name='metrics') metrics_thread.daemon = True metrics_thread.start() beakerd_threads = set(["main_recipes"]) log.debug("starting main recipes thread") main_recipes_thread = threading.Thread(target=main_recipes_loop, name="main_recipes") main_recipes_thread.daemon = True main_recipes_thread.start() try: while True: time.sleep(20) running_threads = set([t.name for t in threading.enumerate()]) if not running_threads.issuperset(beakerd_threads): log.critical("a thread has died, shutting down") rc = 1 running = False event.set() break event.set() event.clear() except (SystemExit, KeyboardInterrupt): log.info("shutting down") running = False event.set() rc = 0 if _threadpool_executor: _threadpool_executor.shutdown() interface.stop() main_recipes_thread.join(10) sys.exit(rc)
def test_populate_installation_from_recipe_resource(self): with self.migration_metadata.bind.connect() as connection: # Populate empty database connection.execute(pkg_resources.resource_string('bkr.inttest.server', 'database-dumps/22.sql')) # Populate test data for migration connection.execute(pkg_resources.resource_string('bkr.inttest.server', 'bz991245-migration-setup.sql')) # Run migration upgrade_db(self.migration_metadata) # Check that installation has been populated for recipe 1 (system_resource) recipe = self.migration_session.query(Recipe).get(1) self.assertEqual(recipe.installation.distro_tree.distro.name, u'distro') self.assertEqual(recipe.installation.kernel_options, u'') # populated below self.assertEqual(recipe.installation.rendered_kickstart.kickstart, u'lol') self.assertEqual(recipe.installation.system.fqdn, u'test.fqdn.name') self.assertEqual(recipe.installation.rebooted, datetime.datetime(2016, 2, 16, 1, 0, 5)) self.assertEqual(recipe.installation.install_started, datetime.datetime(2016, 2, 16, 1, 1, 0)) self.assertEqual(recipe.installation.install_finished, datetime.datetime(2016, 2, 16, 1, 20, 0)) self.assertEqual(recipe.installation.postinstall_finished, datetime.datetime(2016, 2, 16, 1, 21, 0)) self.assertEqual(recipe.installation.created, datetime.datetime(2016, 2, 16, 1, 0, 0)) self.migration_session.close() # Run online data migration (two batches) migration = DataMigration(name=u'commands-for-recipe-installations') finished = migration.migrate_one_batch(self.migration_metadata.bind) self.assertFalse(finished) finished = migration.migrate_one_batch(self.migration_metadata.bind) self.assertTrue(finished) # Check that commands have been associated with their installation recipe = self.migration_session.query(Recipe).get(1) self.assertEqual(recipe.installation.kernel_options, u'ks=lol') installation_cmd = self.migration_session.query(CommandActivity).get(1) self.assertEqual(installation_cmd.installation, recipe.installation) manual_cmd = self.migration_session.query(CommandActivity).get(2) self.assertEqual(manual_cmd.installation, None) reprovision_cmd = self.migration_session.query(CommandActivity).get(3) self.assertEqual(reprovision_cmd.installation, None) # Check that installation has been populated for recipe 2 (guest_resource) recipe = self.migration_session.query(Recipe).get(2) self.assertEqual(recipe.installation.distro_tree.distro.name, u'distro') self.assertEqual(recipe.installation.kernel_options, u'') self.assertEqual(recipe.installation.rendered_kickstart.kickstart, u'lol2') self.assertIsNone(recipe.installation.system) self.assertIsNone(recipe.installation.rebooted) self.assertEqual(recipe.installation.install_started, datetime.datetime(2016, 2, 16, 1, 31, 0)) self.assertEqual(recipe.installation.install_finished, datetime.datetime(2016, 2, 16, 1, 40, 0)) self.assertEqual(recipe.installation.postinstall_finished, datetime.datetime(2016, 2, 16, 1, 41, 0)) self.assertEqual(recipe.installation.created, datetime.datetime(2016, 2, 16, 1, 0, 0)) # Check that installation has been populated for recipes 3 and 4 # (host and guest that never started) recipe = self.migration_session.query(Recipe).get(3) self.assertEqual(recipe.installation.created, datetime.datetime(2016, 2, 17, 0, 0, 0)) recipe = self.migration_session.query(Recipe).get(4) self.assertEqual(recipe.installation.created, datetime.datetime(2016, 2, 17, 0, 0, 0))