def render(self, session, cpu, vendor, speed, comments, **arguments): dbvendor = Vendor.get_unique(session, vendor, compel=True) Cpu.get_unique(session, name=cpu, vendor=dbvendor, speed=speed, preclude=True) dbcpu = Cpu(name=cpu, vendor=dbvendor, speed=speed, comments=comments) session.add(dbcpu) return
def render(self, session, hostname, machine, cpuname, cpuvendor, cpuspeed, cpucount, memory, cluster, share, fullinfo, style, **arguments): if fullinfo or style != 'raw': q = search_hardware_entity_query(session, Machine, **arguments) else: q = search_hardware_entity_query(session, Machine.label, **arguments) if machine: q = q.filter_by(label=machine) if hostname: dns_rec = DnsRecord.get_unique(session, fqdn=hostname, compel=True) q = q.filter(Machine.primary_name_id == dns_rec.id) if cpuname or cpuvendor or cpuspeed is not None: subq = Cpu.get_matching_query(session, name=cpuname, vendor=cpuvendor, speed=cpuspeed, compel=True) q = q.filter(Machine.cpu_id.in_(subq)) if cpucount is not None: q = q.filter_by(cpu_quantity=cpucount) if memory is not None: q = q.filter_by(memory=memory) if cluster: dbcluster = Cluster.get_unique(session, cluster, compel=True) if isinstance(dbcluster, MetaCluster): q = q.join('vm_container', ClusterResource, Cluster) q = q.filter_by(metacluster=dbcluster) else: q = q.join('vm_container', ClusterResource) q = q.filter_by(cluster=dbcluster) q = q.reset_joinpoint() if share: v2shares = session.query(Share.id).filter_by(name=share) if not v2shares.count(): raise NotFoundException("No shares found with name {0}." .format(share)) NasAlias = aliased(VirtualNasDisk) q = q.join('disks', (NasAlias, NasAlias.id == Disk.id)) q = q.filter(NasAlias.share_id.in_(v2shares.subquery())) q = q.reset_joinpoint() if fullinfo or style != "raw": q = q.options(joinedload('location'), subqueryload('interfaces'), lazyload('interfaces.hardware_entity'), joinedload('interfaces.assignments'), joinedload('interfaces.assignments.dns_records'), joinedload('chassis_slot'), subqueryload('chassis_slot.chassis'), subqueryload('disks'), subqueryload('host'), lazyload('host.hardware_entity'), subqueryload('host.services_used'), subqueryload('host._cluster'), lazyload('host._cluster.host')) return q.all() return StringAttributeList(q.all(), "label")
def render(self, session, hostname, machine, cpuname, cpuvendor, cpuspeed, cpucount, memory, cluster, share, fullinfo, style, **arguments): if fullinfo or style != 'raw': q = search_hardware_entity_query(session, Machine, **arguments) else: q = search_hardware_entity_query(session, Machine.label, **arguments) if machine: q = q.filter_by(label=machine) if hostname: dns_rec = DnsRecord.get_unique(session, fqdn=hostname, compel=True) q = q.filter(Machine.primary_name_id==dns_rec.id) if cpuname or cpuvendor or cpuspeed is not None: subq = Cpu.get_matching_query(session, name=cpuname, vendor=cpuvendor, speed=cpuspeed, compel=True) q = q.filter(Machine.cpu_id.in_(subq)) if cpucount is not None: q = q.filter_by(cpu_quantity=cpucount) if memory is not None: q = q.filter_by(memory=memory) if cluster: dbcluster = Cluster.get_unique(session, cluster, compel=True) if isinstance(dbcluster, MetaCluster): q = q.join('vm_container', ClusterResource, Cluster) q = q.filter_by(metacluster=dbcluster) else: q = q.join('vm_container', ClusterResource) q = q.filter_by(cluster=dbcluster) q = q.reset_joinpoint() if share: #v2 v2shares = session.query(Share.id).filter_by(name=share).all() if v2shares: NasAlias = aliased(VirtualDisk) q = q.join('disks', (NasAlias, NasAlias.id == Disk.id)) q = q.filter( NasAlias.share_id.in_(map(lambda s: s[0], v2shares))) q = q.reset_joinpoint() if fullinfo: q = q.options(joinedload('location'), subqueryload('interfaces'), joinedload('interfaces.assignments'), joinedload('interfaces.assignments.dns_records'), joinedload('chassis_slot'), subqueryload('chassis_slot.chassis'), subqueryload('disks'), subqueryload('host'), subqueryload('host.services_used'), subqueryload('host._cluster')) return q.all() return SimpleMachineList(q.all())
def render(self, session, model, vendor, type, cpuname, cpuvendor, cpuspeed, cpunum, memory, disktype, diskcontroller, disksize, nics, nicmodel, nicvendor, comments, **arguments): dbvendor = Vendor.get_unique(session, vendor, compel=True) Model.get_unique(session, name=model, vendor=dbvendor, preclude=True) # Specifically not allowing new models to be added that are of # type aurora_node - that is only meant for the dummy aurora_model. allowed_types = [ "blade", "rackmount", "workstation", "switch", "chassis", "virtual_machine", "nic" ] if type not in allowed_types: raise ArgumentError( "The model's machine type must be one of: %s." % ", ".join(allowed_types)) dbmodel = Model(name=model, vendor=dbvendor, machine_type=type, comments=comments) session.add(dbmodel) session.flush() if cpuname or cpuvendor or cpuspeed is not None: dbcpu = Cpu.get_unique(session, name=cpuname, vendor=cpuvendor, speed=cpuspeed, compel=True) if nicmodel or nicvendor: dbnic = Model.get_unique(session, machine_type='nic', name=nicmodel, vendor=nicvendor, compel=True) else: dbnic = Model.default_nic_model(session) dbmachine_specs = MachineSpecs(model=dbmodel, cpu=dbcpu, cpu_quantity=cpunum, memory=memory, disk_type=disktype, controller_type=diskcontroller, disk_capacity=disksize, nic_count=nics, nic_model=dbnic) session.add(dbmachine_specs) return
def test_create_vm(): #vend = Vendor.get_unique(sess, 'virtual') mod = Model.get_unique(sess, name='vm', compel=True) proc = Cpu.get_unique(sess, name='virtual_cpu', speed=0, compel=True) np = Building.get_unique(sess, 'np', compel=True) for i in xrange(NUM_MACHINES): vm = Machine(label='%s%s'%(VM_NAME, i), location=np, model=mod, cpu=proc, cpu_quantity=1, memory=4196) create(sess, vm) machines = sess.query(Machine).filter(Machine.label.like(VM_NAME+'%')).all() assert len(machines) is NUM_MACHINES print 'created %s machines' % (len(machines))
def test_create_machines_for_hosts(): np = Building.get_unique(sess, name='np', compel=True) am = Model.get_unique(sess, name='vm', compel=True) a_cpu = Cpu.get_unique(sess, name='aurora_cpu', compel=True) for i in xrange(NUM_HOSTS): machine = Machine(label='%s%s'% (MACHINE_NAME, i), location=np, model=am, cpu=a_cpu, cpu_quantity=8, memory=32768) create(sess, machine) machines = sess.query(Machine).filter( Machine.label.like(MACHINE_NAME+'%')).all() assert len(machines) is NUM_MACHINES print 'created %s esx machines' % len(machines)
def render(self, session, cpu, vendor, speed, **arguments): dbcpu = Cpu.get_unique(session, name=cpu, vendor=vendor, speed=speed, compel=True) q = session.query(MachineSpecs) q = q.filter_by(cpu=dbcpu) q = q.join((Model, MachineSpecs.model_id == Model.id), Vendor) q = q.order_by(Vendor.name, Model.name) if q.count(): models = ", ".join(["%s/%s" % (spec.model.vendor.name, spec.model.name) for spec in q]) raise ArgumentError("{0} is still used by the following models, " "and cannot be deleted: {1!s}" .format(dbcpu, models)) session.delete(dbcpu) session.flush() return
def test_create_machines_for_hosts(): np = Building.get_unique(sess, name='np', compel=True) am = Model.get_unique(sess, name='vm', compel=True) a_cpu = Cpu.get_unique(sess, name='aurora_cpu', compel=True) for i in xrange(NUM_HOSTS): machine = Machine(label='%s%s' % (MACHINE_NAME, i), location=np, model=am, cpu=a_cpu, cpu_quantity=8, memory=32768) create(sess, machine) machines = sess.query(Machine).filter( Machine.label.like(MACHINE_NAME + '%')).all() assert len(machines) is NUM_MACHINES print 'created %s esx machines' % len(machines)
def test_create_vm(): #vend = Vendor.get_unique(sess, 'virtual') mod = Model.get_unique(sess, name='vm', compel=True) proc = Cpu.get_unique(sess, name='virtual_cpu', speed=0, compel=True) np = Building.get_unique(sess, 'np', compel=True) for i in xrange(NUM_MACHINES): vm = Machine(label='%s%s' % (VM_NAME, i), location=np, model=mod, cpu=proc, cpu_quantity=1, memory=4196) create(sess, vm) machines = sess.query(Machine).filter(Machine.label.like(VM_NAME + '%')).all() assert len(machines) is NUM_MACHINES print 'created %s machines' % (len(machines))
def render(self, session, model, vendor, type, cpuname, cpuvendor, cpuspeed, cpunum, memory, disktype, diskcontroller, disksize, nics, nicmodel, nicvendor, comments, **arguments): dbvendor = Vendor.get_unique(session, vendor, compel=True) Model.get_unique(session, name=model, vendor=dbvendor, preclude=True) # Specifically not allowing new models to be added that are of # type aurora_node - that is only meant for the dummy aurora_model. if type.isAuroraChassis() or type.isAuroraNode(): raise ArgumentError("The model's machine type must not be" " an aurora type") dbmodel = Model(name=model, vendor=dbvendor, model_type=type, comments=comments) session.add(dbmodel) session.flush() if cpuname or cpuvendor or cpuspeed is not None: if not type.isMachineType(): raise ArgumentError("Machine specfications are only valid" " for machine types") dbcpu = Cpu.get_unique(session, name=cpuname, vendor=cpuvendor, speed=cpuspeed, compel=True) if nicmodel or nicvendor: dbnic = Model.get_unique(session, model_type=NicType.Nic, name=nicmodel, vendor=nicvendor, compel=True) else: dbnic = Model.default_nic_model(session) dbmachine_specs = MachineSpecs(model=dbmodel, cpu=dbcpu, cpu_quantity=cpunum, memory=memory, disk_type=disktype, controller_type=diskcontroller, disk_capacity=disksize, nic_count=nics, nic_model=dbnic) session.add(dbmachine_specs) return
def render(self, session, model, vendor, type, cpuname, cpuvendor, cpuspeed, cpunum, memory, disktype, diskcontroller, disksize, nics, nicmodel, nicvendor, comments, **arguments): dbvendor = Vendor.get_unique(session, vendor, compel=True) Model.get_unique(session, name=model, vendor=dbvendor, preclude=True) # Specifically not allowing new models to be added that are of # type aurora_node - that is only meant for the dummy aurora_model. allowed_types = ["blade", "rackmount", "workstation", "switch", "chassis", "virtual_machine", "nic"] if type not in allowed_types: raise ArgumentError("The model's machine type must be one of: %s." % ", ".join(allowed_types)) dbmodel = Model(name=model, vendor=dbvendor, machine_type=type, comments=comments) session.add(dbmodel) session.flush() if cpuname or cpuvendor or cpuspeed is not None: dbcpu = Cpu.get_unique(session, name=cpuname, vendor=cpuvendor, speed=cpuspeed, compel=True) if nicmodel or nicvendor: dbnic = Model.get_unique(session, machine_type='nic', name=nicmodel, vendor=nicvendor, compel=True) else: dbnic = Model.default_nic_model(session) dbmachine_specs = MachineSpecs(model=dbmodel, cpu=dbcpu, cpu_quantity=cpunum, memory=memory, disk_type=disktype, controller_type=diskcontroller, disk_capacity=disksize, nic_count=nics, nic_model=dbnic) session.add(dbmachine_specs) return
def render(self, session, cpu, vendor, speed, **arguments): dbcpu = Cpu.get_unique(session, name=cpu, vendor=vendor, speed=speed, compel=True) q = session.query(MachineSpecs) q = q.filter_by(cpu=dbcpu) q = q.join((Model, MachineSpecs.model_id == Model.id), Vendor) q = q.order_by(Vendor.name, Model.name) if q.count(): models = ", ".join([ "%s/%s" % (spec.model.vendor.name, spec.model.name) for spec in q ]) raise ArgumentError("{0} is still used by the following models, " "and cannot be deleted: {1!s}".format( dbcpu, models)) session.delete(dbcpu) session.flush() return
def render(self, session, logger, model, vendor, newmodel, newvendor, comments, leave_existing, **arguments): for (arg, value) in arguments.items(): # Cleaning the strings isn't strictly necessary but allows # for simple equality checks below and removes the need to # call refresh(). if arg in ['newmodel', 'newvendor', 'machine_type', 'cpuname', 'cpuvendor', 'disktype', 'diskcontroller', 'nicmodel', 'nicvendor']: if value is not None: arguments[arg] = value.lower().strip() dbmodel = Model.get_unique(session, name=model, vendor=vendor, compel=True) if leave_existing and (newmodel or newvendor): raise ArgumentError("Cannot update model name or vendor without " "updating any existing machines.") fix_existing = not leave_existing dbmachines = set() # The sub-branching here is a little difficult to read... # Basically, there are three different checks to handle # setting a new vendor, a new name, or both. if newvendor: dbnewvendor = Vendor.get_unique(session, newvendor, compel=True) if newmodel: Model.get_unique(session, name=newmodel, vendor=dbnewvendor, preclude=True) else: Model.get_unique(session, name=dbmodel.name, vendor=dbnewvendor, preclude=True) dbmodel.vendor = dbnewvendor if newmodel: if not newvendor: Model.get_unique(session, name=newmodel, vendor=dbmodel.vendor, preclude=True) dbmodel.name = newmodel if newvendor or newmodel: q = session.query(Machine).filter_by(model=dbmodel) dbmachines.update(q.all()) # For now, can't update machine_type. There are too many spots # that special case things like aurora_node or virtual_machine to # know that the transistion is safe. If there is enough need we # can always add those transitions later. if arguments['machine_type'] is not None: raise UnimplementedError("Cannot (yet) change a model's " "machine type.") if comments: dbmodel.comments = comments # The comments also do not affect the templates. cpu_args = ['cpuname', 'cpuvendor', 'cpuspeed'] cpu_info = dict([(self.argument_lookup[arg], arguments[arg]) for arg in cpu_args]) cpu_values = [v for v in cpu_info.values() if v is not None] nic_args = ['nicmodel', 'nicvendor'] nic_info = dict([(self.argument_lookup[arg], arguments[arg]) for arg in nic_args]) nic_values = [v for v in nic_info.values() if v is not None] spec_args = ['cpunum', 'memory', 'disktype', 'diskcontroller', 'disksize', 'nics'] specs = dict([(self.argument_lookup[arg], arguments[arg]) for arg in spec_args]) spec_values = [v for v in specs.values() if v is not None] if not dbmodel.machine_specs: if cpu_values or nic_values or spec_values: if not cpu_values or len(spec_values) < len(spec_args): raise ArgumentError("Missing required parameters to store " "machine specs for the model. Please " "give all CPU, disk, RAM, and NIC " "count information.") dbcpu = Cpu.get_unique(session, compel=True, **cpu_info) if nic_values: dbnic = Model.get_unique(session, compel=True, machine_type='nic', **nic_info) else: dbnic = Model.default_nic_model(session) dbmachine_specs = MachineSpecs(model=dbmodel, cpu=dbcpu, nic_model=dbnic, **specs) session.add(dbmachine_specs) # Anything below that updates specs should have been verified above. if cpu_values: dbcpu = Cpu.get_unique(session, compel=True, **cpu_info) self.update_machine_specs(model=dbmodel, dbmachines=dbmachines, attr='cpu', value=dbcpu, fix_existing=fix_existing) for arg in ['memory', 'cpunum']: if arguments[arg] is not None: self.update_machine_specs(model=dbmodel, dbmachines=dbmachines, attr=self.argument_lookup[arg], value=arguments[arg], fix_existing=fix_existing) if arguments['disktype']: if fix_existing: raise ArgumentError("Please specify --leave_existing to " "change the model disktype. This cannot " "be converted automatically.") dbmodel.machine_specs.disk_type = arguments['disktype'] for arg in ['diskcontroller', 'disksize']: if arguments[arg] is not None: self.update_disk_specs(model=dbmodel, dbmachines=dbmachines, attr=self.argument_lookup[arg], value=arguments[arg], fix_existing=fix_existing) if nic_values: dbnic = Model.get_unique(session, compel=True, **nic_info) self.update_interface_specs(model=dbmodel, dbmachines=dbmachines, value=dbnic, fix_existing=fix_existing) if arguments['nics'] is not None: dbmodel.machine_specs.nic_count = arguments['nics'] session.flush() plenaries = PlenaryCollection(logger=logger) for dbmachine in dbmachines: plenaries.append(PlenaryMachineInfo(dbmachine, logger=logger)) plenaries.write() return
def render(self, session, logger, model, vendor, newmodel, newvendor, comments, leave_existing, **arguments): for (arg, value) in arguments.items(): # Cleaning the strings isn't strictly necessary but allows # for simple equality checks below and removes the need to # call refresh(). if arg in [ 'newmodel', 'newvendor', 'machine_type', 'cpuname', 'cpuvendor', 'disktype', 'diskcontroller', 'nicmodel', 'nicvendor' ]: if value is not None: arguments[arg] = value.lower().strip() dbmodel = Model.get_unique(session, name=model, vendor=vendor, compel=True) if leave_existing and (newmodel or newvendor): raise ArgumentError("Cannot update model name or vendor without " "updating any existing machines.") fix_existing = not leave_existing dbmachines = set() # The sub-branching here is a little difficult to read... # Basically, there are three different checks to handle # setting a new vendor, a new name, or both. if newvendor: dbnewvendor = Vendor.get_unique(session, newvendor, compel=True) if newmodel: Model.get_unique(session, name=newmodel, vendor=dbnewvendor, preclude=True) else: Model.get_unique(session, name=dbmodel.name, vendor=dbnewvendor, preclude=True) dbmodel.vendor = dbnewvendor if newmodel: if not newvendor: Model.get_unique(session, name=newmodel, vendor=dbmodel.vendor, preclude=True) dbmodel.name = newmodel if newvendor or newmodel: q = session.query(Machine).filter_by(model=dbmodel) dbmachines.update(q.all()) # For now, can't update machine_type. There are too many spots # that special case things like aurora_node or virtual_machine to # know that the transistion is safe. If there is enough need we # can always add those transitions later. if arguments['machine_type'] is not None: raise UnimplementedError("Cannot (yet) change a model's " "machine type.") if comments: dbmodel.comments = comments # The comments also do not affect the templates. cpu_args = ['cpuname', 'cpuvendor', 'cpuspeed'] cpu_info = dict([(self.argument_lookup[arg], arguments[arg]) for arg in cpu_args]) cpu_values = [v for v in cpu_info.values() if v is not None] nic_args = ['nicmodel', 'nicvendor'] nic_info = dict([(self.argument_lookup[arg], arguments[arg]) for arg in nic_args]) nic_values = [v for v in nic_info.values() if v is not None] spec_args = [ 'cpunum', 'memory', 'disktype', 'diskcontroller', 'disksize', 'nics' ] specs = dict([(self.argument_lookup[arg], arguments[arg]) for arg in spec_args]) spec_values = [v for v in specs.values() if v is not None] if not dbmodel.machine_specs: if cpu_values or nic_values or spec_values: if not cpu_values or len(spec_values) < len(spec_args): raise ArgumentError("Missing required parameters to store " "machine specs for the model. Please " "give all CPU, disk, RAM, and NIC " "count information.") dbcpu = Cpu.get_unique(session, compel=True, **cpu_info) if nic_values: dbnic = Model.get_unique(session, compel=True, machine_type='nic', **nic_info) else: dbnic = Model.default_nic_model(session) dbmachine_specs = MachineSpecs(model=dbmodel, cpu=dbcpu, nic_model=dbnic, **specs) session.add(dbmachine_specs) # Anything below that updates specs should have been verified above. if cpu_values: dbcpu = Cpu.get_unique(session, compel=True, **cpu_info) self.update_machine_specs(model=dbmodel, dbmachines=dbmachines, attr='cpu', value=dbcpu, fix_existing=fix_existing) for arg in ['memory', 'cpunum']: if arguments[arg] is not None: self.update_machine_specs(model=dbmodel, dbmachines=dbmachines, attr=self.argument_lookup[arg], value=arguments[arg], fix_existing=fix_existing) if arguments['disktype']: if fix_existing: raise ArgumentError("Please specify --leave_existing to " "change the model disktype. This cannot " "be converted automatically.") dbmodel.machine_specs.disk_type = arguments['disktype'] for arg in ['diskcontroller', 'disksize']: if arguments[arg] is not None: self.update_disk_specs(model=dbmodel, dbmachines=dbmachines, attr=self.argument_lookup[arg], value=arguments[arg], fix_existing=fix_existing) if nic_values: dbnic = Model.get_unique(session, compel=True, **nic_info) self.update_interface_specs(model=dbmodel, dbmachines=dbmachines, value=dbnic, fix_existing=fix_existing) if arguments['nics'] is not None: dbmodel.machine_specs.nic_count = arguments['nics'] session.flush() plenaries = PlenaryCollection(logger=logger) for dbmachine in dbmachines: plenaries.append(PlenaryMachineInfo(dbmachine, logger=logger)) plenaries.write() return
def render(self, session, logger, machine, model, vendor, serial, chassis, slot, clearchassis, multislot, vmhost, cluster, allow_metacluster_change, cpuname, cpuvendor, cpuspeed, cpucount, memory, ip, **arguments): dbmachine = Machine.get_unique(session, machine, compel=True) plenaries = PlenaryCollection(logger=logger) oldinfo = DSDBRunner.snapshot_hw(dbmachine) if clearchassis: del dbmachine.chassis_slot[:] remove_plenaries = PlenaryCollection(logger=logger) if chassis: dbchassis = Chassis.get_unique(session, chassis, compel=True) if machine_plenary_will_move(old=dbmachine.location, new=dbchassis.location): remove_plenaries.append(Plenary.get_plenary(dbmachine)) dbmachine.location = dbchassis.location if slot is None: raise ArgumentError("Option --chassis requires --slot " "information.") self.adjust_slot(session, logger, dbmachine, dbchassis, slot, multislot) elif slot is not None: dbchassis = None for dbslot in dbmachine.chassis_slot: if dbchassis and dbslot.chassis != dbchassis: raise ArgumentError("Machine in multiple chassis, please " "use --chassis argument.") dbchassis = dbslot.chassis if not dbchassis: raise ArgumentError("Option --slot requires --chassis " "information.") self.adjust_slot(session, logger, dbmachine, dbchassis, slot, multislot) dblocation = get_location(session, **arguments) if dblocation: loc_clear_chassis = False for dbslot in dbmachine.chassis_slot: dbcl = dbslot.chassis.location if dbcl != dblocation: if chassis or slot is not None: raise ArgumentError("{0} conflicts with chassis {1!s} " "location {2}.".format(dblocation, dbslot.chassis, dbcl)) else: loc_clear_chassis = True if loc_clear_chassis: del dbmachine.chassis_slot[:] if machine_plenary_will_move(old=dbmachine.location, new=dblocation): remove_plenaries.append(Plenary.get_plenary(dbmachine)) dbmachine.location = dblocation if model or vendor: # If overriding model, should probably overwrite default # machine specs as well. if not model: model = dbmachine.model.name if not vendor: vendor = dbmachine.model.vendor.name dbmodel = Model.get_unique(session, name=model, vendor=vendor, compel=True) if dbmodel.machine_type not in ['blade', 'rackmount', 'workstation', 'aurora_node', 'virtual_machine']: raise ArgumentError("The update_machine command cannot update " "machines of type %s." % dbmodel.machine_type) # We probably could do this by forcing either cluster or # location data to be available as appropriate, but really? # Failing seems reasonable. if dbmodel.machine_type != dbmachine.model.machine_type and \ 'virtual_machine' in [dbmodel.machine_type, dbmachine.model.machine_type]: raise ArgumentError("Cannot change machine from %s to %s." % (dbmachine.model.machine_type, dbmodel.machine_type)) old_nic_model = dbmachine.model.nic_model new_nic_model = dbmodel.nic_model if old_nic_model != new_nic_model: for iface in dbmachine.interfaces: if iface.model == old_nic_model: iface.model = new_nic_model dbmachine.model = dbmodel if cpuname or cpuvendor or cpuspeed is not None: dbcpu = Cpu.get_unique(session, name=cpuname, vendor=cpuvendor, speed=cpuspeed, compel=True) dbmachine.cpu = dbcpu if cpucount is not None: dbmachine.cpu_quantity = cpucount if memory is not None: dbmachine.memory = memory if serial: dbmachine.serial_no = serial if ip: update_primary_ip(session, dbmachine, ip) # FIXME: For now, if a machine has its interface(s) in a portgroup # this command will need to be followed by an update_interface to # re-evaluate the portgroup for overflow. # It would be better to have --pg and --autopg options to let it # happen at this point. if cluster or vmhost: if not dbmachine.vm_container: raise ArgumentError("Cannot convert a physical machine to " "virtual.") old_holder = dbmachine.vm_container.holder.holder_object resholder = get_resource_holder(session, hostname=vmhost, cluster=cluster, compel=False) new_holder = resholder.holder_object # TODO: do we want to allow moving machines between the cluster and # metacluster level? if new_holder.__class__ != old_holder.__class__: raise ArgumentError("Cannot move a VM between a cluster and a " "stand-alone host.") if cluster: if new_holder.metacluster != old_holder.metacluster \ and not allow_metacluster_change: raise ArgumentError("Current {0:l} does not match " "new {1:l}." .format(old_holder.metacluster, new_holder.metacluster)) remove_plenaries.append(Plenary.get_plenary(dbmachine.vm_container)) dbmachine.vm_container.holder = resholder for dbdisk in dbmachine.disks: if not isinstance(dbdisk, VirtualDisk): continue old_share = dbdisk.share if isinstance(old_share.holder, BundleResource): resourcegroup = old_share.holder.name else: resourcegroup = None new_share = find_share(new_holder, resourcegroup, old_share.name, error=ArgumentError) # If the shares are registered at the metacluster level and both # clusters are in the same metacluster, then there will be no # real change here if new_share != old_share: old_share.disks.remove(dbdisk) new_share.disks.append(dbdisk) if isinstance(new_holder, Cluster): dbmachine.location = new_holder.location_constraint else: dbmachine.location = new_holder.location session.flush() plenaries.append(Plenary.get_plenary(old_holder)) plenaries.append(Plenary.get_plenary(new_holder)) if dbmachine.vm_container: plenaries.append(Plenary.get_plenary(dbmachine.vm_container)) session.flush() # Check if the changed parameters still meet cluster capacity # requiremets if dbmachine.cluster: dbmachine.cluster.validate() if allow_metacluster_change: dbmachine.cluster.metacluster.validate() if dbmachine.host and dbmachine.host.cluster: dbmachine.host.cluster.validate() # The check to make sure a plenary file is not written out for # dummy aurora hardware is within the call to write(). This way # it is consistent without altering (and forgetting to alter) # all the calls to the method. plenaries.append(Plenary.get_plenary(dbmachine)) if remove_plenaries.plenaries and dbmachine.host: plenaries.append(Plenary.get_plenary(dbmachine.host)) key = CompileKey.merge([plenaries.get_write_key(), remove_plenaries.get_remove_key()]) try: lock_queue.acquire(key) remove_plenaries.stash() plenaries.write(locked=True) remove_plenaries.remove(locked=True) if dbmachine.host: # XXX: May need to reconfigure. pass dsdb_runner = DSDBRunner(logger=logger) dsdb_runner.update_host(dbmachine, oldinfo) dsdb_runner.commit_or_rollback("Could not update machine in DSDB") except: plenaries.restore_stash() remove_plenaries.restore_stash() raise finally: lock_queue.release(key) return
def render(self, session, logger, machine, model, vendor, serial, chassis, slot, clearchassis, multislot, vmhost, cluster, allow_metacluster_change, cpuname, cpuvendor, cpuspeed, cpucount, memory, ip, uri, **arguments): dbmachine = Machine.get_unique(session, machine, compel=True) oldinfo = DSDBRunner.snapshot_hw(dbmachine) plenaries = PlenaryCollection(logger=logger) plenaries.append(Plenary.get_plenary(dbmachine)) if dbmachine.vm_container: plenaries.append(Plenary.get_plenary(dbmachine.vm_container)) if dbmachine.host: # Using PlenaryHostData directly, to avoid warnings if the host has # not been configured yet plenaries.append(PlenaryHostData.get_plenary(dbmachine.host)) if clearchassis: del dbmachine.chassis_slot[:] if chassis: dbchassis = Chassis.get_unique(session, chassis, compel=True) dbmachine.location = dbchassis.location if slot is None: raise ArgumentError("Option --chassis requires --slot " "information.") self.adjust_slot(session, logger, dbmachine, dbchassis, slot, multislot) elif slot is not None: dbchassis = None for dbslot in dbmachine.chassis_slot: if dbchassis and dbslot.chassis != dbchassis: raise ArgumentError("Machine in multiple chassis, please " "use --chassis argument.") dbchassis = dbslot.chassis if not dbchassis: raise ArgumentError("Option --slot requires --chassis " "information.") self.adjust_slot(session, logger, dbmachine, dbchassis, slot, multislot) dblocation = get_location(session, **arguments) if dblocation: loc_clear_chassis = False for dbslot in dbmachine.chassis_slot: dbcl = dbslot.chassis.location if dbcl != dblocation: if chassis or slot is not None: raise ArgumentError("{0} conflicts with chassis {1!s} " "location {2}." .format(dblocation, dbslot.chassis, dbcl)) else: loc_clear_chassis = True if loc_clear_chassis: del dbmachine.chassis_slot[:] dbmachine.location = dblocation if dbmachine.host: for vm in dbmachine.host.virtual_machines: plenaries.append(Plenary.get_plenary(vm)) vm.location = dblocation if model or vendor: # If overriding model, should probably overwrite default # machine specs as well. if not model: model = dbmachine.model.name if not vendor: vendor = dbmachine.model.vendor.name dbmodel = Model.get_unique(session, name=model, vendor=vendor, compel=True) if not dbmodel.model_type.isMachineType(): raise ArgumentError("The update_machine command cannot update " "machines of type %s." % dbmodel.model_type) # We probably could do this by forcing either cluster or # location data to be available as appropriate, but really? # Failing seems reasonable. if dbmodel.model_type != dbmachine.model.model_type and \ (dbmodel.model_type.isVirtualMachineType() or dbmachine.model.model_type.isVirtualMachineType()): raise ArgumentError("Cannot change machine from %s to %s." % (dbmachine.model.model_type, dbmodel.model_type)) old_nic_model = dbmachine.model.nic_model new_nic_model = dbmodel.nic_model if old_nic_model != new_nic_model: for iface in dbmachine.interfaces: if iface.model == old_nic_model: iface.model = new_nic_model dbmachine.model = dbmodel if cpuname or cpuvendor or cpuspeed is not None: dbcpu = Cpu.get_unique(session, name=cpuname, vendor=cpuvendor, speed=cpuspeed, compel=True) dbmachine.cpu = dbcpu if cpucount is not None: dbmachine.cpu_quantity = cpucount if memory is not None: dbmachine.memory = memory if serial: dbmachine.serial_no = serial if ip: update_primary_ip(session, logger, dbmachine, ip) if uri and not dbmachine.model.model_type.isVirtualAppliance(): raise ArgumentError("URI can be specified only for virtual " "appliances and the model's type is %s" % dbmachine.model.model_type) if uri: dbmachine.uri = uri # FIXME: For now, if a machine has its interface(s) in a portgroup # this command will need to be followed by an update_interface to # re-evaluate the portgroup for overflow. # It would be better to have --pg and --autopg options to let it # happen at this point. if cluster or vmhost: if not dbmachine.vm_container: raise ArgumentError("Cannot convert a physical machine to " "virtual.") old_holder = dbmachine.vm_container.holder.holder_object resholder = get_resource_holder(session, hostname=vmhost, cluster=cluster, compel=False) new_holder = resholder.holder_object if self.get_metacluster(new_holder) != self.get_metacluster(old_holder) \ and not allow_metacluster_change: raise ArgumentError("Current {0:l} does not match " "new {1:l}." .format(self.get_metacluster(old_holder), self.get_metacluster(new_holder))) plenaries.append(Plenary.get_plenary(old_holder)) plenaries.append(Plenary.get_plenary(new_holder)) dbmachine.vm_container.holder = resholder for dbdisk in dbmachine.disks: if isinstance(dbdisk, VirtualNasDisk): old_share = dbdisk.share if isinstance(old_share.holder, BundleResource): resourcegroup = old_share.holder.resourcegroup.name else: resourcegroup = None new_share = find_resource(Share, new_holder, resourcegroup, old_share.name, error=ArgumentError) # If the shares are registered at the metacluster level and both # clusters are in the same metacluster, then there will be no # real change here if new_share != old_share: old_share.disks.remove(dbdisk) new_share.disks.append(dbdisk) if isinstance(dbdisk, VirtualLocalDisk): old_filesystem = dbdisk.filesystem new_filesystem = find_resource(Filesystem, new_holder, None, old_filesystem.name, error=ArgumentError) if new_filesystem != old_filesystem: old_filesystem.disks.remove(dbdisk) new_filesystem.disks.append(dbdisk) if isinstance(new_holder, Cluster): dbmachine.location = new_holder.location_constraint else: # vmhost dbmachine.location = new_holder.hardware_entity.location session.flush() # Check if the changed parameters still meet cluster capacity # requiremets if dbmachine.cluster: dbmachine.cluster.validate() if allow_metacluster_change: dbmachine.cluster.metacluster.validate() if dbmachine.host and dbmachine.host.cluster: dbmachine.host.cluster.validate() # The check to make sure a plenary file is not written out for # dummy aurora hardware is within the call to write(). This way # it is consistent without altering (and forgetting to alter) # all the calls to the method. with plenaries.get_key(): plenaries.stash() try: plenaries.write(locked=True) dsdb_runner = DSDBRunner(logger=logger) dsdb_runner.update_host(dbmachine, oldinfo) dsdb_runner.commit_or_rollback("Could not update machine in DSDB") except: plenaries.restore_stash() raise return