def doit(): distro_trees = [] for id in request.form.getlist('distro_tree_id'): try: distro_trees.append(DistroTree.by_id(id)) except NoResultFound: raise BadRequest400('Distro tree %r does not exist' % id) job_details = {} job_details['pick'] = request.form.get('pick') or 'auto' if job_details['pick'] == 'fqdn': try: job_details['system'] = System.by_fqdn(request.form.get('system'), identity.current.user) except NoResultFound: raise BadRequest400('System %s not found' % request.form.get('system')) elif job_details['pick'] == 'lab': try: job_details['lab'] = LabController.by_name(request.form.get('lab')) except NoResultFound: raise BadRequest400('Lab controller %s not found' % request.form.get('lab')) days = int(request.form.get('reserve_days') or DEFAULT_RESERVE_DAYS) days = min(days, MAX_DAYS_PROVISION) job_details['reservetime'] = days * 24 * 60 * 60 job_details['whiteboard'] = request.form.get('whiteboard') job_details['ks_meta'] = request.form.get('ks_meta') job_details['koptions'] = request.form.get('koptions') job_details['koptions_post'] = request.form.get('koptions_post') with convert_internal_errors(): job = Job.provision_system_job(distro_trees, **job_details) return 'Created %s' % job.t_id, 201, [('Location', url('/jobs/%s' % job.id))]
def test_create_system_set_host_hypervisor(self): fqdn = data_setup.unique_name(u'mysystem%s') run_client(['bkr', 'system-create', fqdn, '--host-hypervisor=KVM']) with session.begin(): system = System.by_fqdn(fqdn, User.by_user_name(u'admin')) self.assertEquals(str(system.hypervisor), u'KVM') self.assertEquals(system.activity[0].new_value, u'KVM')
def test_creating_a_system_with_power_settings(self): s = requests.Session() s.post(get_server_base() + 'login', data={'user_name': self.user.user_name, 'password': u'password'}).raise_for_status() fqdn = data_setup.unique_name(u'newsystem%s') data = { 'fqdn': fqdn, 'lab_controller_id': self.lc.id, 'power_type': u'apc_snmp_then_etherwake', 'power_address': u'dummyaddress', 'power_user': u'dummyuser', 'power_password': u'dummypassword', 'power_id': u'dummyvm', 'power_quiescent_period': 5, 'release_action': u'LeaveOn', 'reprovision_distro_tree': {'id': self.distro_tree.id}, } response = post_json(get_server_base() + 'systems/', session=s, data=data) with session.begin(): system = System.by_fqdn(fqdn, self.user) self.assertEquals(system.power.power_type, PowerType.by_name(u'apc_snmp_then_etherwake')) self.assertEquals(system.power.power_address, u'dummyaddress') self.assertEquals(system.power.power_user, u'dummyuser') self.assertEquals(system.power.power_passwd, u'dummypassword') self.assertEquals(system.power.power_id, u'dummyvm') self.assertEquals(system.power.power_quiescent_period, 5) self.assertEquals(system.release_action, ReleaseAction.leave_on) self.assertEquals(system.reprovision_distro_tree, self.distro_tree)
def doit(): distro_trees = [] for id in request.form.getlist('distro_tree_id'): try: distro_trees.append(DistroTree.by_id(id)) except NoResultFound: raise BadRequest400('Distro tree %r does not exist' % id) job_details = {} job_details['pick'] = request.form.get('pick') or 'auto' if job_details['pick'] == 'fqdn': try: job_details['system'] = System.by_fqdn(request.form.get('system'), identity.current.user) except NoResultFound: raise BadRequest400('System %s not found' % request.form.get('system')) elif job_details['pick'] == 'lab': try: job_details['lab'] = LabController.by_name(request.form.get('lab')) except NoResultFound: raise BadRequest400('Lab controller %s not found' % request.form.get('lab')) days = int(request.form.get('reserve_days') or DEFAULT_RESERVE_DAYS) days = min(days, MAX_DAYS_PROVISION) job_details['reservetime'] = days * 24 * 60 * 60 job_details['whiteboard'] = request.form.get('whiteboard') job_details['ks_meta'] = request.form.get('ks_meta') job_details['koptions'] = request.form.get('koptions') job_details['koptions_post'] = request.form.get('koptions_post') with convert_internal_errors(): job = Job.provision_system_job(distro_trees, **job_details) return 'Created %s' % job.t_id, 201, [('Location', absolute_url('/jobs/%s' % job.id))]
def test_creating_a_system_with_hardware_essentials(self): s = requests.Session() s.post(get_server_base() + 'login', data={ 'user_name': self.user.user_name, 'password': u'password' }).raise_for_status() fqdn = data_setup.unique_name(u'newsystem%s') data = { 'fqdn': fqdn, 'lab_controller_id': self.lc.id, 'arches': [u'i386', u'x86_64'], 'location': u'dummylocation', 'lender': u'dummylender', 'kernel_type': u'highbank' } response = post_json(get_server_base() + 'systems/', session=s, data=data) with session.begin(): system = System.by_fqdn(fqdn, self.user) self.assertEquals(system.fqdn, fqdn) self.assertEquals(system.lab_controller_id, self.lc.id) self.assertTrue(Arch.by_name(u'i386') in system.arch) self.assertTrue(Arch.by_name(u'x86_64') in system.arch) self.assertEquals(system.location, u'dummylocation') self.assertEquals(system.lender, u'dummylender') self.assertEquals(system.kernel_type, KernelType.by_name(u'highbank'))
def test_lookup_secret_fqdn(self): with session.begin(): system = data_setup.create_system() system.private = True lab_controller_user = LabController.by_name(self.lc_fqdn).user system2 = System.by_fqdn(str(system.fqdn), user=lab_controller_user) self.assertEquals(system, system2)
def test_creating_a_system_with_hardware_details(self): s = requests.Session() s.post(get_server_base() + 'login', data={ 'user_name': self.user.user_name, 'password': u'password' }).raise_for_status() fqdn = data_setup.unique_name(u'newsystem%s') data = { 'fqdn': fqdn, 'hypervisor': u'KVM', 'vendor': u'dummyvendor', 'location': u'dummylocation', 'model': u'dummymodel', 'serial_number': u'dummynumber', 'mac_address': u'dummymacaddress', 'memory': 111111, 'numa_nodes': 5, } response = post_json(get_server_base() + 'systems/', session=s, data=data) with session.begin(): system = System.by_fqdn(fqdn, self.user) self.assertEquals(system.fqdn, fqdn) self.assertEquals(system.hypervisor, Hypervisor.by_name(u'KVM')) self.assertEquals(system.location, u'dummylocation') self.assertEquals(system.serial, u'dummynumber') self.assertEquals(system.mac_address, u'dummymacaddress') self.assertEquals(system.memory, 111111) self.assertEquals(system.numa.nodes, 5)
def get_installation_for_system(self, fqdn): system = System.by_fqdn(fqdn, identity.current.user) if not system.installations: raise ValueError('System %s has never been provisioned' % fqdn) installation = system.installations[0] distro_tree = installation.distro_tree distro_tree_url = distro_tree.url_in_lab(system.lab_controller, 'http') if not distro_tree_url: raise ValueError('No usable URL found for distro tree %s in lab %s' % (distro_tree.id, system.lab_controller.fqdn)) if system.kernel_type.uboot: by_kernel = ImageType.uimage by_initrd = ImageType.uinitrd else: by_kernel = ImageType.kernel by_initrd = ImageType.initrd kernel = distro_tree.image_by_type(by_kernel, system.kernel_type) if not kernel: raise ValueError('Kernel image not found for distro tree %s' % distro_tree.id) initrd = distro_tree.image_by_type(by_initrd, system.kernel_type) if not initrd: raise ValueError('Initrd image not found for distro tree %s' % distro_tree.id) return { 'kernel_url': urlparse.urljoin(distro_tree_url, kernel.path), 'initrd_url': urlparse.urljoin(distro_tree_url, initrd.path), 'kernel_options': installation.kernel_options or '', 'distro_tree_urls': [lca.url for lca in distro_tree.lab_controller_assocs if lca.lab_controller == system.lab_controller], }
def test_creating_a_system_with_hardware_details(self): s = requests.Session() s.post(get_server_base() + 'login', data={'user_name': self.user.user_name, 'password': u'password'}).raise_for_status() fqdn = data_setup.unique_name(u'newsystem%s') data = { 'fqdn': fqdn, 'hypervisor': u'KVM', 'vendor': u'dummyvendor', 'location': u'dummylocation', 'model': u'dummymodel', 'serial_number': u'dummynumber', 'mac_address': u'dummymacaddress', 'memory': 111111, 'numa_nodes': 5, } response = post_json(get_server_base() + 'systems/', session=s, data=data) with session.begin(): system = System.by_fqdn(fqdn, self.user) self.assertEquals(system.fqdn, fqdn) self.assertEquals(system.hypervisor, Hypervisor.by_name(u'KVM')) self.assertEquals(system.location, u'dummylocation') self.assertEquals(system.serial, u'dummynumber') self.assertEquals(system.mac_address, u'dummymacaddress') self.assertEquals(system.memory, 111111) self.assertEquals(system.numa.nodes, 5)
def test_create_system_set_labcontroller(self): fqdn = data_setup.unique_name(u'mysystem%s') lc = data_setup.create_labcontroller() run_client(['bkr', 'system-create', '--lab-controller', str(lc.fqdn), fqdn]) with session.begin(): system = System.by_fqdn(fqdn, User.by_user_name(u'admin')) self.assertTrue(system.lab_controller, lc)
def save_system(self, **kw): try: with convert_db_lookup_error('No such system: %s' % kw['system']['text']): system = System.by_fqdn(kw['system']['text'], identity.current.user) except DatabaseLookupError, e: flash(unicode(e)) redirect("./edit?group_id=%s" % kw['group_id'])
def update_loan(self, fqdn=None, loaned=None, loan_comment=None, **kw): """Update system loan and loan comment. Returns the loanee """ # The formal param 'loaned' is dictated to us by widgets.SystemForm... loaning_to = loaned system = System.by_fqdn(fqdn, identity.current.user) system.change_loan(loaning_to, loan_comment) return loaning_to if loaning_to else ''
def test_create_system_set_arches(self): fqdn = data_setup.unique_name(u'mysystem%s') run_client(['bkr', 'system-create', '--arch', u'i386', '--arch', u'x86_64', fqdn]) with session.begin(): system = System.by_fqdn(fqdn, User.by_user_name(u'admin')) self.assertIn(Arch.by_name(u'i386'), system.arch) self.assertIn(Arch.by_name(u'x86_64'), system.arch)
def clear_netboot_form(self, fqdn): """Queues the clear netboot commands Enqueues the command to clear any netboot configuration for this system, and on success redirects to the system page. """ system = System.by_fqdn(fqdn, identity.current.user) system.clear_netboot(service=u'WEBUI') flash(_(u'Clear netboot command enqueued')) redirect(u'../view/%s' % fqdn)
def clear_netboot(self, fqdn): """ Clears any netboot configuration in effect for the system with the given fully-qualified domain name. .. verisonadded:: 0.9 """ system = System.by_fqdn(fqdn, identity.current.user) system.clear_netboot(service=u'XMLRPC') return system.fqdn # because turbogears makes us return something
def test_create_system_set_condition(self): fqdn = data_setup.unique_name(u'mysystem%s') with session.begin(): lc = data_setup.create_labcontroller() run_client(['bkr', 'system-create', fqdn, '--lab-controller', str(lc.fqdn), '--condition=Automated']) with session.begin(): system = System.by_fqdn(fqdn, User.by_user_name(u'admin')) self.assertTrue(system.lab_controller, lc) self.assertEquals(str(system.status), u'Automated')
def test_create_system_set_condition(self): fqdn = data_setup.unique_name(u'mysystem%s') with session.begin(): lc = data_setup.create_labcontroller() run_client([ 'bkr', 'system-create', fqdn, '--lab-controller', str(lc.fqdn), '--condition=Automated' ]) with session.begin(): system = System.by_fqdn(fqdn, User.by_user_name(u'admin')) self.assertTrue(system.lab_controller, lc) self.assertEquals(str(system.status), u'Automated')
def check_power_action(self, action): with session.begin(): user = data_setup.create_user(password=u'password') system = data_setup.create_system() data_setup.configure_system_power(system) system.lab_controller = self.lab_controller system.user = None self.server.auth.login_password(user.user_name, 'password') self.server.systems.power(action, system.fqdn) self.assertEqual( System.by_fqdn(system.fqdn, user).command_queue[0].action, action)
def add_completed_command(self, fqdn, action): # Reports completion of a command that was executed # synchronously by the lab controller user = identity.current.user system = System.by_fqdn(fqdn, user) cmd = Command(user=user, service=u"XMLRPC", action=action, status=CommandStatus.completed) cmd.start_time = cmd.finish_time = datetime.utcnow() system.command_queue.append(cmd) session.flush() # Populates cmd.system (needed for next call) cmd.log_to_system_history() return True
def release(self, fqdn): """ Releases a reservation on the system with the given fully-qualified domain name. The caller must be the current user of a system (i.e. must have successfully reserved it previously). .. versionadded:: 0.6 """ system = System.by_fqdn(fqdn, identity.current.user) system.unreserve_manually_reserved(service=u'XMLRPC') return system.fqdn # because turbogears makes us return something
def add_completed_command(self, fqdn, action): # Reports completion of a command that was executed # synchronously by the lab controller user = identity.current.user system = System.by_fqdn(fqdn, user) cmd = CommandActivity(user=user, service=u"XMLRPC", action=action, status=CommandStatus.completed) system.command_queue.append(cmd) session.flush() # Populates cmd.system (needed for next call) cmd.log_to_system_history() return True
def reserve(self, fqdn): """ "Reserves" (a.k.a. "takes") the system with the given fully-qualified domain name. The caller then becomes the user of the system, and can provision it at will. A system may only be reserved when: its condition is 'Manual', it is not currently in use, and the caller has permission to use the system. .. versionadded:: 0.6 """ system = System.by_fqdn(fqdn, identity.current.user) system.reserve_manually(service=u'XMLRPC') return system.fqdn # because turbogears makes us return something
def history(self, fqdn, since=None): """ Returns the history for the given system. If the *since* argument is given, all history entries between that timestamp and the present are returned. By default, history entries from the past 24 hours are returned. History entries are returned as a list of structures (dicts), each of which has the following keys: 'created' Timestamp of the activity 'user' Username of the user who performed the action 'service' Service by which the action was performed (e.g. 'XMLRPC') 'action' Action which was performed (e.g. 'Changed') 'field_name' Name of the field which was acted upon 'old_value' Value of the field before the action (if any) 'new_value' Value of the field after the action (if any) Note that field names and actions are recorded in human-readable form, which might not be ideal for machine parsing. All timestamps are expressed in UTC. .. versionadded:: 0.6.6 """ if since is None: since = datetime.datetime.utcnow() - datetime.timedelta(days=1) else: if not isinstance(since, datetime.datetime): raise TypeError("'since' must be an XML-RPC datetime") system = System.by_fqdn(fqdn, identity.current.user) activities = SystemActivity.query.filter( and_(SystemActivity.object == system, SystemActivity.created >= since)) return [ dict(created=a.created, user=a.user.user_name, service=a.service, action=a.action, field_name=a.field_name, old_value=a.old_value, new_value=a.new_value) for a in activities ]
def update_loan(self, fqdn=None, loaned=None, loan_comment=None, **kw): """Update system loan and loan comment. Returns the loanee """ # The formal param 'loaned' is dictated to us by widgets.SystemForm... loaning_to = loaned system = System.by_fqdn(fqdn, identity.current.user) try: system.change_loan(loaning_to, loan_comment) except ValueError as exc: raise cherrypy.HTTPError(400, str(exc)) except InsufficientSystemPermissions as exc: raise cherrypy.HTTPError(403, str(exc)) return loaning_to if loaning_to else ''
def test_create_system_defaults(self): fqdn = data_setup.unique_name(u'mysystem%s') run_client(['bkr', 'system-create', fqdn]) with session.begin(): system = System.by_fqdn(fqdn, User.by_user_name(u'admin')) self.assertTrue(system.owner.user_name, data_setup.ADMIN_USER) self.assertTrue(system.custom_access_policy.grants_everybody( SystemPermission.view)) # duplicate try: run_client(['bkr', 'system-create', fqdn]) self.fail('Must fail') except ClientError as e: self.assertIn("System with fqdn %r already exists" % fqdn, e.stderr_output)
def submit_inventory_job(): """ Submit a inventory job with the most suitable distro selected automatically. Returns a dictionary consisting of the job_id, recipe_id, status (recipe status) and the job XML. If ``dryrun`` is set to ``True`` in the request, the first three are set to ``None``. :jsonparam string fqdn: Fully-qualified domain name for the system. :jsonparam bool dryrun: If True, do not submit the job """ if 'fqdn' not in request.json: raise BadRequest400('Missing the fqdn parameter') fqdn = request.json['fqdn'] if 'dryrun' in request.json: dryrun = request.json['dryrun'] else: dryrun = False try: system = System.by_fqdn(fqdn, identity.current.user) except NoResultFound: raise BadRequest400('System not found: %s' % fqdn) if system.find_current_hardware_scan_recipe(): raise Conflict409('Hardware scanning already in progress') distro = system.distro_tree_for_inventory() if not distro: raise BadRequest400( 'Could not find a compatible distro for hardware scanning available to this system' ) job_details = {} job_details['system'] = system job_details['whiteboard'] = 'Update Inventory for %s' % fqdn with convert_internal_errors(): job_xml = Job.inventory_system_job(distro, dryrun=dryrun, **job_details) r = {} if not dryrun: r = system.find_current_hardware_scan_recipe().__json__() else: r = { 'recipe_id': None, 'status': None, 'job_id': None, } r['job_xml'] = job_xml r = jsonify(r) return r
def test_return_loan(self): with session.begin(): user = data_setup.create_user(password='******') # Login as admin, loan to average Joe, b = self.browser login(b) self.go_to_loan_page() self.change_loan(user.user_name) logout(b) # Login as average Joe, and click 'Return Loan' login(b, user.user_name, 'password') self.go_to_loan_page() b.find_element_by_name('update_loan.return').click() self.verify_loan_update('') logout(b) # Login as admin, loan to self and add comment login(b) comment = u'As I pee, sir, I see Pisa!' self.go_to_loan_page() self.change_loan(u'admin', comment) self.verify_loan_update(u'admin') sys = self.system # Test going from '' -> comment in SystemActivity sys_activity_comment = sys.dyn_activity.filter(SystemActivity.field_name == \ u'Loan Comment').first() self.assertEqual(sys_activity_comment.old_value, u'') self.assertEqual(sys_activity_comment.new_value, comment) # Let's clear the user field b.find_element_by_name('update_loan.loaned').clear() b.find_element_by_name('update_loan.update').click() # This is equivalent to a loan return b.find_element_by_xpath('//textarea[@name=' '"update_loan.loan_comment" and normalize-space(text())=""]') self.verify_loan_update('') # Test going from 'admin' -> '' in SystemActivity sys = System.by_fqdn(self.system.fqdn, user) sys_activity_name = sys.dyn_activity.filter(SystemActivity.field_name == \ u'Loaned To').first() self.assertEqual(sys_activity_name.old_value, u'admin') self.assertEqual(sys_activity_name.new_value, u'') # Test going from comment -> '' in SystemActivity sys_activity_comment2 = sys.dyn_activity.filter(SystemActivity.field_name == \ u'Loan Comment').first() self.assertEqual(sys_activity_comment2.old_value, comment) self.assertEqual(sys_activity_comment2.new_value, u'')
def test_creating_a_system_with_scheduler_settings(self): s = requests.Session() s.post(get_server_base() + 'login', data={'user_name': self.user.user_name, 'password': u'password'}).raise_for_status() fqdn = data_setup.unique_name(u'newsystem%s') data = { 'fqdn': fqdn, 'status': u'Broken', 'status_reason': u'Currently is broken', 'type': u'Laptop', } response = post_json(get_server_base() + 'systems/', session=s, data=data) with session.begin(): system = System.by_fqdn(fqdn, self.user) self.assertEquals(system.status, SystemStatus.broken) self.assertEquals(system.status_reason, u'Currently is broken') self.assertEquals(system.type, SystemType.laptop)
def history(self, fqdn, since=None): """ Returns the history for the given system. If the *since* argument is given, all history entries between that timestamp and the present are returned. By default, history entries from the past 24 hours are returned. History entries are returned as a list of structures (dicts), each of which has the following keys: 'created' Timestamp of the activity 'user' Username of the user who performed the action 'service' Service by which the action was performed (e.g. 'XMLRPC') 'action' Action which was performed (e.g. 'Changed') 'field_name' Name of the field which was acted upon 'old_value' Value of the field before the action (if any) 'new_value' Value of the field after the action (if any) Note that field names and actions are recorded in human-readable form, which might not be ideal for machine parsing. All timestamps are expressed in UTC. .. versionadded:: 0.6.6 """ if since is None: since = datetime.datetime.utcnow() - datetime.timedelta(days=1) else: if not isinstance(since, datetime.datetime): raise TypeError("'since' must be an XML-RPC datetime") system = System.by_fqdn(fqdn, identity.current.user) activities = SystemActivity.query.filter(and_( SystemActivity.object == system, SystemActivity.created >= since)) return [dict(created=a.created, user=a.user.user_name, service=a.service, action=a.action, field_name=a.field_name, old_value=a.old_value, new_value=a.new_value) for a in activities]
def doit(): distro_trees = [] for id in request.form.getlist('distro_tree_id'): try: distro_trees.append(DistroTree.by_id(id)) except NoResultFound: raise BadRequest400('Distro tree %r does not exist' % id) job_details = {} job_details['pick'] = request.form.get('pick') or 'auto' system_choice = 'any system' if job_details['pick'] == 'fqdn': try: job_details['system'] = System.by_fqdn(request.form.get('system'), identity.current.user) system_choice = 'a specific system' except DatabaseLookupError: raise BadRequest400('System %s not found' % request.form.get('system')) elif job_details['pick'] == 'lab': try: job_details['lab'] = LabController.by_name(request.form.get('lab')) system_choice = 'any lab system' except NoResultFound: raise BadRequest400('Lab controller %s not found' % request.form.get('lab')) reservetime = int( request.form.get('reserve_duration') or DEFAULT_RESERVE_SECONDS) if reservetime > MAX_SECONDS_PROVISION: raise BadRequest400( 'Reservation time exceeds maximum time of %s hours' % MAX_HOURS_PROVISION) job_details['reservetime'] = reservetime job_details['whiteboard'] = request.form.get('whiteboard') if not job_details['whiteboard']: job_details['whiteboard'] = ( "Reserve Workflow provision of distro %s on %s for %d seconds" % (request.form.get('distro'), system_choice, job_details['reservetime'])) job_details['ks_meta'] = request.form.get('ks_meta') job_details['koptions'] = request.form.get('koptions') job_details['koptions_post'] = request.form.get('koptions_post') with convert_internal_errors(): job = Job.provision_system_job(distro_trees, **job_details) return 'Created %s' % job.t_id, 201, [('Location', absolute_url('/jobs/%s' % job.id))]
def postreboot(self, recipe_id=None): # Backwards compat only, delete this after 0.10: # the recipe_id arg used to be hostname try: int(recipe_id) except ValueError: system = System.by_fqdn(recipe_id, identity.current.user) system.action_power('reboot', service=u'XMLRPC', delay=30) return system.fqdn try: recipe = Recipe.by_id(int(recipe_id)) except (InvalidRequestError, NoResultFound, ValueError): raise BX(_('Invalid recipe ID %s') % recipe_id) if isinstance(recipe.resource, SystemResource): recipe.resource.system.action_power('reboot', service=u'XMLRPC', delay=30) return True
def get_osmajor_arches(self, fqdn, tags=None): """ Returns a dict of all distro families with a list of arches that apply for system. If *tags* is given, limits to distros with at least one of the given tags. {"RedHatEnterpriseLinux3": ["i386", "x86_64"],} .. versionadded:: 0.11.0 """ system = System.by_fqdn(fqdn, identity.current.user) query = system.distro_trees(only_in_lab=False) if tags: query = query.filter(Distro._tags.any(DistroTag.tag.in_(tags))) query = query.join(DistroTree.arch).distinct() result = {} for osmajor, arch in query.values(OSMajor.osmajor, Arch.arch): result.setdefault(osmajor, []).append(arch) return result
def save_system(self, **kw): system = System.by_fqdn(kw['system']['text'],identity.current.user) # A system owner can add their system to a group, but a group owner # *cannot* add an arbitrary system to their group because that would # grant them extra privileges over it. if not system.can_edit(identity.current.user): flash(_(u'You do not have permission to edit system %s' % system)) redirect('edit?group_id=%s' % kw['group_id']) group = Group.by_id(kw['group_id']) if group in system.groups: flash( _(u"System '%s' is already in group '%s'" % (system.fqdn, group.group_name))) redirect("./edit?group_id=%s" % kw['group_id']) group.systems.append(system) activity = GroupActivity(identity.current.user, u'WEBUI', u'Added', u'System', u"", system.fqdn) sactivity = SystemActivity(identity.current.user, u'WEBUI', u'Added', u'Group', u"", group.display_name) group.activity.append(activity) system.activity.append(sactivity) flash( _(u"OK") ) redirect("./edit?group_id=%s" % kw.get('group_id'))
def test_return_loan(self): with session.begin(): user = data_setup.create_user(password='******') # Login as admin, loan to average Joe, b = self.browser login(b) self.go_to_loan_page() self.change_loan(user.user_name) logout(b) # Login as average Joe, and click 'Return Loan' login(b, user.user_name, 'password') self.go_to_loan_page() self.return_loan() self.verify_loan_update('') logout(b) # Login as admin, loan to self and add comment login(b) comment = u'As I pee, sir, I see Pisa!' self.go_to_loan_page() self.change_loan(u'admin', comment) self.verify_loan_update(u'admin') sys = self.system # Test going from '' -> comment in SystemActivity sys_activity_comment = sys.dyn_activity.filter(SystemActivity.field_name == \ u'Loan Comment').first() self.assertEqual(sys_activity_comment.old_value, u'') self.assertEqual(sys_activity_comment.new_value, comment) # Let's return the loan self.return_loan() self.verify_loan_update('') # Test going from 'admin' -> '' in SystemActivity sys = System.by_fqdn(self.system.fqdn, user) sys_activity_name = sys.dyn_activity.filter(SystemActivity.field_name == \ u'Loaned To').first() self.assertEqual(sys_activity_name.old_value, u'admin') self.assertEqual(sys_activity_name.new_value, u'') # Test going from comment -> '' in SystemActivity sys_activity_comment2 = sys.dyn_activity.filter(SystemActivity.field_name == \ u'Loan Comment').first() self.assertEqual(sys_activity_comment2.old_value, comment) self.assertEqual(sys_activity_comment2.new_value, u'')
def delete(self, fqdn): """ Delete a system with the given fully-qualified domain name. The caller must be the owner of the system or an admin. :param fqdn: fully-qualified domain name of the system to be deleted :type fqdn: string .. versionadded:: 0.8.2 """ system = System.by_fqdn(fqdn, identity.current.user) if system.reservations: raise ValueError("Can't delete system %s with reservations" % fqdn) if system.owner != identity.current.user and \ not identity.current.user.is_admin(): raise ValueError("Can't delete system %s you don't own" % fqdn) session.delete(system) return 'Deleted %s' % fqdn
def submit_inventory_job(): """ Submit a inventory job with the most suitable distro selected automatically. Returns a dictionary consisting of the job_id, recipe_id, status (recipe status) and the job XML. If ``dryrun`` is set to ``True`` in the request, the first three are set to ``None``. :jsonparam string fqdn: Fully-qualified domain name for the system. :jsonparam bool dryrun: If True, do not submit the job """ if 'fqdn' not in request.json: raise BadRequest400('Missing the fqdn parameter') fqdn = request.json['fqdn'] if 'dryrun' in request.json: dryrun = request.json['dryrun'] else: dryrun = False try: system = System.by_fqdn(fqdn, identity.current.user) except NoResultFound: raise BadRequest400('System not found: %s' % fqdn) if system.find_current_hardware_scan_recipe(): raise Conflict409('Hardware scanning already in progress') distro = system.distro_tree_for_inventory() if not distro: raise BadRequest400('Could not find a compatible distro for hardware scanning available to this system') job_details = {} job_details['system'] = system job_details['whiteboard'] = 'Update Inventory for %s' % fqdn with convert_internal_errors(): job_xml = Job.inventory_system_job(distro, dryrun=dryrun, **job_details) r = {} if not dryrun: r = system.find_current_hardware_scan_recipe().__json__() else: r = {'recipe_id': None, 'status': None, 'job_id': None, } r['job_xml'] = job_xml r = jsonify(r) return r
def power(self, action, fqdn, clear_netboot=False, force=False, delay=0): """ Controls power for the system with the given fully-qualified domain name. If the *clear_netboot* argument is True, the Cobbler netboot configuration for the system will be cleared before power controlling. Controlling power for a system is not normally permitted when the system is in use by someone else, because it is likely to interfere with their usage. Callers may pass True for the *force* argument to override this safety check. This method does not wait for Cobbler to report whether the power control was succesful. :param action: 'on', 'off', or 'reboot' :type action: string :param fqdn: fully-qualified domain name of the system to be power controlled :type fqdn: string :param clear_netboot: whether to clear netboot configuration before powering :type clear_netboot: boolean :param force: whether to power the system even if it is in use :type force: boolean :param delay: number of seconds to delay before performing the action (default none) :type delay: int or float .. versionadded:: 0.6 .. versionchanged:: 0.6.14 No longer waits for completion of Cobbler power task. """ system = System.by_fqdn(fqdn, identity.current.user) if not system.can_power(identity.current.user): raise InsufficientSystemPermissions( _(u'User %s does not have permission to power system %s') % (identity.current.user, system)) if not force and system.user is not None \ and system.user != identity.current.user: raise BX(_(u'System is in use')) if clear_netboot: system.clear_netboot(service=u'XMLRPC') system.action_power(action, service=u'XMLRPC', delay=delay) return system.fqdn # because turbogears makes us return something
def _get_distro_options(self, osmajor=None, tag=None, system=None, **kwargs): """ Returns a list of distro names for the given osmajor and tag. """ if not osmajor: return [] distros = Distro.query.join(Distro.osversion, OSVersion.osmajor)\ .filter(Distro.trees.any(DistroTree.lab_controller_assocs.any()))\ .filter(OSMajor.osmajor == osmajor)\ .order_by(Distro.date_created.desc()) if tag: distros = distros.filter(Distro._tags.any(DistroTag.tag == tag)) if system: try: system = System.by_fqdn(system, identity.current.user) except NoResultFound: return [] distros = system.distros(query=distros) return [name for name, in distros.values(Distro.name)]
def add_system_to_pool(pool_name): """ Add a system to a system pool :param pool_name: System pool's name. :jsonparam fqdn: System's fully-qualified domain name. """ u = identity.current.user data = read_json_request(request) pool = _get_pool_by_name(pool_name, lockmode='update') if 'fqdn' not in data: raise BadRequest400('System FQDN not specified') try: system = System.by_fqdn(data['fqdn'], u) except NoResultFound: raise BadRequest400("System '%s' does not exist" % data['fqdn']) if not pool in system.pools: if pool.can_edit(u) and system.can_edit(u): system.record_activity(user=u, service=u'HTTP', action=u'Added', field=u'Pool', old=None, new=unicode(pool)) system.pools.append(pool) system.date_modified = datetime.datetime.utcnow() pool.record_activity(user=u, service=u'HTTP', action=u'Added', field=u'System', old=None, new=unicode(system)) else: if not pool.can_edit(u): raise Forbidden403('You do not have permission to ' 'add systems to pool %s' % pool.name) if not system.can_edit(u): raise Forbidden403('You do not have permission to ' 'modify system %s' % system.fqdn) return '', 204
def _get_distro_tree_options(self, distro=None, system=None, **kwargs): """ Returns a list of distro trees for the given distro. """ if not distro: return [] try: distro = Distro.by_name(distro) except DatabaseLookupError: return [] trees = distro.dyn_trees.join(DistroTree.arch)\ .filter(DistroTree.lab_controller_assocs.any())\ .order_by(DistroTree.variant, Arch.arch) if system: try: system = System.by_fqdn(system, identity.current.user) except NoResultFound: return [] trees = system.distro_trees(query=trees) return [(tree.id, unicode(tree)) for tree in trees]
def _get_distro_tree_options(self, distro=None, system=None, **kwargs): """ Returns a list of distro trees for the given distro. """ if not distro: return [] try: distro = Distro.by_name(distro) except DatabaseLookupError: return [] trees = distro.dyn_trees.join(DistroTree.arch)\ .filter(DistroTree.lab_controller_assocs.any())\ .order_by(DistroTree.variant, Arch.arch) if system: try: system = System.by_fqdn(system, identity.current.user) except DatabaseLookupError: return [] trees = system.distro_trees(query=trees) return [(tree.id, unicode(tree)) for tree in trees]
def test_creating_a_system_with_scheduler_settings(self): s = requests.Session() s.post(get_server_base() + 'login', data={ 'user_name': self.user.user_name, 'password': u'password' }).raise_for_status() fqdn = data_setup.unique_name(u'newsystem%s') data = { 'fqdn': fqdn, 'status': u'Broken', 'status_reason': u'Currently is broken', 'type': u'Laptop', } response = post_json(get_server_base() + 'systems/', session=s, data=data) with session.begin(): system = System.by_fqdn(fqdn, self.user) self.assertEquals(system.status, SystemStatus.broken) self.assertEquals(system.status_reason, u'Currently is broken') self.assertEquals(system.type, SystemType.laptop)
def test_create_system_set_power_settings(self): fqdn = data_setup.unique_name(u'mysystem%s') distro_tree = data_setup.create_distro_tree() run_client([ 'bkr', 'system-create', '--power-type', u'apc_snmp_then_etherwake', '--power-address', u'dummyaddress', '--power-user', u'dummyuser', '--power-password', u'dummypassword', '--power-id', u'dummyvm', '--power-quiescent-period', u'5', '--release-action', u'LeaveOn', '--reprovision-distro-tree', str(distro_tree.id), fqdn ]) with session.begin(): system = System.by_fqdn(fqdn, User.by_user_name(u'admin')) self.assertEquals(system.power.power_type, PowerType.by_name(u'apc_snmp_then_etherwake')) self.assertEquals(system.power.power_address, u'dummyaddress') self.assertEquals(system.power.power_user, u'dummyuser') self.assertEquals(system.power.power_passwd, u'dummypassword') self.assertEquals(system.power.power_id, u'dummyvm') self.assertEquals(system.power.power_quiescent_period, 5) self.assertEquals(system.release_action, ReleaseAction.leave_on) self.assertEquals(system.reprovision_distro_tree, distro_tree)
def _get_distro_options(self, osmajor=None, tag=None, system=None, **kwargs): """ Returns a list of distro names for the given osmajor and tag. """ if not osmajor: return [] distros = Distro.query.join(Distro.osversion, OSVersion.osmajor)\ .filter(Distro.trees.any(DistroTree.lab_controller_assocs.any()))\ .filter(OSMajor.osmajor == osmajor)\ .order_by(Distro.date_created.desc()) if tag: distros = distros.filter(Distro._tags.any(DistroTag.tag == tag)) if system: try: system = System.by_fqdn(system, identity.current.user) except DatabaseLookupError: return [] distros = system.distros(query=distros) return [name for name, in distros.values(Distro.name)]
def test_creating_a_system_with_power_settings(self): s = requests.Session() s.post(get_server_base() + 'login', data={ 'user_name': self.user.user_name, 'password': u'password' }).raise_for_status() fqdn = data_setup.unique_name(u'newsystem%s') data = { 'fqdn': fqdn, 'lab_controller_id': self.lc.id, 'power_type': u'apc_snmp_then_etherwake', 'power_address': u'dummyaddress', 'power_user': u'dummyuser', 'power_password': u'dummypassword', 'power_id': u'dummyvm', 'power_quiescent_period': 5, 'release_action': u'LeaveOn', 'reprovision_distro_tree': { 'id': self.distro_tree.id }, } response = post_json(get_server_base() + 'systems/', session=s, data=data) with session.begin(): system = System.by_fqdn(fqdn, self.user) self.assertEquals(system.power.power_type, PowerType.by_name(u'apc_snmp_then_etherwake')) self.assertEquals(system.power.power_address, u'dummyaddress') self.assertEquals(system.power.power_user, u'dummyuser') self.assertEquals(system.power.power_passwd, u'dummypassword') self.assertEquals(system.power.power_id, u'dummyvm') self.assertEquals(system.power.power_quiescent_period, 5) self.assertEquals(system.release_action, ReleaseAction.leave_on) self.assertEquals(system.reprovision_distro_tree, self.distro_tree)
def test_lookup_secret_fqdn(self): with session.begin(): system = data_setup.create_system(private=True) lab_controller_user = LabController.by_name(self.lc_fqdn).user system2 = System.by_fqdn(str(system.fqdn), user=lab_controller_user) self.assertEquals(system, system2)
def _to_python(self, value, state): try: system = System.by_fqdn(value, identity.current.user) except NoResultFound: raise Invalid('Invalid system', value, state) return system