예제 #1
0
def change_address(
        vm_hostname, new_address,
        offline=False, migrate=False, allow_reserved_hv=False,
        offline_transport='drbd',
):
    """Change VMs IP address

    This is done by changing data in Serveradmin, running Puppet in VM and
    rebooting it.
    """

    if not offline:
        raise IGVMError('IP address change can be only performed offline')

    with _get_vm(vm_hostname) as vm:
        new_address = ip_address(new_address)

        if vm.dataset_obj['intern_ip'] == new_address:
            raise ConfigError('New IP address is the same as the old one!')

        if not vm.hypervisor.get_vlan_network(new_address) and not migrate:
            err = 'Current hypervisor does not support new subnet!'
            raise ConfigError(err)

        new_network = Query(
            {
                'servertype': 'route_network',
                'state': 'online',
                'network_type': 'internal',
                'intern_ip': Contains(new_address),
            }
        ).get()['hostname']

        vm_was_running = vm.is_running()

        with Transaction() as transaction:
            if vm_was_running:
                vm.shutdown(
                    transaction=transaction,
                    check_vm_up_on_transaction=False,
                )
            vm.change_address(
                new_address, new_network, transaction=transaction,
            )

            if migrate:
                vm_migrate(
                    vm_object=vm,
                    run_puppet=True, offline=True, no_shutdown=True,
                    allow_reserved_hv=allow_reserved_hv,
                    offline_transport=offline_transport,
                )
            else:
                vm.hypervisor.mount_vm_storage(vm, transaction=transaction)
                vm.run_puppet()
                vm.hypervisor.redefine_vm(vm)
                vm.hypervisor.umount_vm_storage(vm)

            if vm_was_running:
                vm.start()
예제 #2
0
파일: vm.py 프로젝트: innogames/igvm
    def check_serveradmin_config(self):
        """Validate relevant Serveradmin attributes"""

        mul_numa_nodes = 128 * self.hypervisor.num_numa_nodes()
        validations = [
            (
                'hostname',
                re_compile(r'\A[a-z][a-z0-9\.\-]+\Z').match,
                'invalid hostname',
            ),
            ('memory', lambda v: v > 0, 'memory must be > 0'),
            # https://medium.com/@juergen_thomann/memory-hotplug-with-qemu-kvm-and-libvirt-558f1c635972#.sytig6o9h
            (
                'memory',
                lambda v: v % mul_numa_nodes == 0,
                'memory must be multiple of {}MiB'.format(mul_numa_nodes),
            ),
            ('num_cpu', lambda v: v > 0, 'num_cpu must be > 0'),
            ('os', lambda v: True, 'os must be set'),
            (
                'disk_size_gib',
                lambda v: v > 0,
                'disk_size_gib must be > 0',
            ),
            ('puppet_ca', lambda v: True, 'puppet_ca must be set'),
            ('puppet_master', lambda v: True, 'puppet_master must be set'),
        ]

        for attr, check, err in validations:
            value = self.dataset_obj[attr]
            if not value:
                raise ConfigError('"{}" attribute is not set'.format(attr))
            if not check(value):
                raise ConfigError(err)
예제 #3
0
def vm_rename(vm_hostname, new_hostname, offline=False):
    """Redefine the VM on the same hypervisor with a different name

    We can only do this operation offline.  If the VM is online, it needs
    to be shut down.  No data will be lost.
    """

    with _get_vm(vm_hostname) as vm:

        if vm.dataset_obj['puppet_disabled']:
            raise ConfigError(
                'Rename command only works with Puppet enabled'
            )

        _check_defined(vm)

        if not offline:
            raise NotImplementedError(
                'Rename command only works with --offline at the moment.'
            )
        if not vm.is_running():
            raise NotImplementedError(
                'Rename command only works online at the moment.'
            )

        vm.rename(new_hostname)
예제 #4
0
def vm_rename(vm_hostname, new_hostname, offline=False):
    """Redefine the VM on the same hypervisor with a different name

    We can only do this operation offline.  If the VM is online, it needs
    to be shut down.  No data will be lost.
    """

    with _get_vm(vm_hostname) as vm:
        if vm.dataset_obj['datacenter_type'] not in ['aws.dct', 'kvm.dct']:
            raise NotImplementedError(
                'This operation is not yet supported for {}'.format(
                    vm.dataset_obj['datacenter_type']))

        if vm.dataset_obj['puppet_disabled']:
            raise ConfigError('Rename command only works with Puppet enabled')

        if vm.dataset_obj['datacenter_type'] == 'kvm.dct':
            _check_defined(vm)

            if not offline:
                raise NotImplementedError(
                    'Rename command only works with --offline at the moment.')
            if not vm.is_running():
                raise NotImplementedError(
                    'Rename command only works online at the moment.')

            vm.rename(new_hostname)
        elif vm.dataset_obj['datacenter_type'] == 'aws.dct':
            vm.aws_rename(new_hostname)
예제 #5
0
파일: hypervisor.py 프로젝트: seqizz/igvm
    def vm_set_num_cpu(self, vm, num_cpu):
        """Change the number of CPUs of a VM"""
        self._check_committed(vm)
        self._check_attribute_synced(vm, 'num_cpu')

        if num_cpu < 1:
            raise ConfigError('Invalid num_cpu value: {}'.format(num_cpu))

        log.info('Changing #CPUs of "{}" on "{}" from {} to {}...'.format(
            vm.fqdn, self.fqdn, vm.dataset_obj['num_cpu'], num_cpu))

        # If VM is offline, we can just rebuild the domain
        if not self.vm_running(vm):
            log.info('VM is offline, rebuilding domain with new settings')
            vm.dataset_obj['num_cpu'] = num_cpu
            self.redefine_vm(vm)
        else:
            set_vcpus(self, vm, self._get_domain(vm), num_cpu)

        # Validate changes
        # We can't rely on the hypervisor to provide data on VMs all the time.
        updated_dataset_obj = self.vm_sync_from_hypervisor(vm)
        current_num_cpu = updated_dataset_obj['num_cpu']
        if current_num_cpu != num_cpu:
            raise HypervisorError(
                'New CPUs are not visible to hypervisor, changes will not be '
                'committed.')

        vm.dataset_obj['num_cpu'] = num_cpu
        vm.dataset_obj.commit()
예제 #6
0
def get_puppet_ca(vm):
    puppet_ca_type = Query(
        {
            'hostname': vm['puppet_ca']
        },
        ['servertype'],
    ).get()['servertype']

    if puppet_ca_type not in ['vm', 'public_domain']:
        raise ConfigError(
            'Servertype {} not supported for puppet_ca'.format(
                puppet_ca_type, ), )

    if puppet_ca_type == 'vm':
        return vm['puppet_ca']

    ca_query = Query(
        {'domain': vm['puppet_ca']},
        [{
            'lb_nodes': ['hostname', 'state']
        }],
    )
    ca_hosts = [
        lb_node['hostname'] for res in ca_query for lb_node in res['lb_nodes']
        if lb_node['state'] in ['online', 'deploy_online']
    ]
    random.shuffle(ca_hosts)

    return ca_hosts[0]
예제 #7
0
    def format_vm_storage(self, vm, transaction=None):
        """Create new filesystem for VM and mount it. Returns mount path."""

        if self.vm_defined(vm):
            raise InvalidStateError(
                'Refusing to format storage of defined VM "{}".'.format(
                    vm.fqdn))

        mkfs_options = XFS_CONFIG.get(vm.dataset_obj['os'])

        if not mkfs_options:
            raise ConfigError('No mkfs options defined for OS {}'.format(
                vm.dataset_obj['os']))

        self.format_storage(self.get_volume_by_vm(vm).path(), mkfs_options)
        return self.mount_vm_storage(vm, transaction)
예제 #8
0
파일: commands.py 프로젝트: Phantuman/igvm
def change_address(vm_hostname, new_address, offline=False):
    """Change VMs IP address

    This is done by changing data in Serveradmin, running Puppet in VM and
    rebooting it.
    """

    if not offline:
        raise IGVMError('IP address change can be only performed offline')

    with _get_vm(vm_hostname) as vm:
        if vm.dataset_obj['igvm_operation_mode'] != 'kvm':
            raise NotImplementedError(
                'This operation is not yet supported for {}'.format(
                    vm.dataset_obj['igvm_operation_mode']))

        old_address = vm.dataset_obj['intern_ip']
        new_address = ip_address(new_address)

        if old_address == new_address:
            raise ConfigError('New IP address is the same as the old one!')

        vm_was_running = vm.is_running()

        vm.dataset_obj['intern_ip'] = new_address
        vm.dataset_obj.commit()

        if vm_was_running:
            vm.shutdown()

        try:
            with Transaction() as transaction:
                vm.hypervisor.mount_vm_storage(vm, transaction)
                vm.run_puppet()
                vm.hypervisor.redefine_vm(vm)
                vm.hypervisor.umount_vm_storage(vm)
                if vm_was_running:
                    vm.start()
        except BaseException:
            vm.dataset_obj['intern_ip'] = old_address
            vm.dataset_obj.commit()
            raise
예제 #9
0
파일: hypervisor.py 프로젝트: seqizz/igvm
 def _check_committed(self, vm):
     """Check that the given VM has no uncommitted changes"""
     if vm.dataset_obj.is_dirty():
         raise ConfigError(
             'VM object has uncommitted changes, commit them first!')