Exemple #1
0
    def test_vm_directory_already_exists(self):
        """Attempt to create a VM whilst the directory for the VM already exists"""
        # Create the directory for the VM
        os.makedirs(VirtualMachine._get_vm_dir(self.test_vms['TEST_VM_1']['name']))

        # Attempt to create VM, expecting an exception for the directory already existing
        with self.assertRaises(VmDirectoryAlreadyExistsException):
            self.parser.parse_arguments('create %s' % self.test_vms['TEST_VM_1']['name'] +
                                        ' --cpu-count %s --disk-size %s --memory %s' %
                                        (self.test_vms['TEST_VM_1']['cpu_count'],
                                         self.test_vms['TEST_VM_1']['disk_size'][0],
                                         self.test_vms['TEST_VM_1']['memory_allocation']) +
                                        ' --network %s --storage-type %s' %
                                        (self.test_vms['TEST_VM_1']['networks'][0],
                                         'Local'))

        # Ensure the VM has not been created
        self.assertFalse(self.vm_factory.check_exists(self.test_vms['TEST_VM_1']['name']))

        # Remove directory
        shutil.rmtree(VirtualMachine._get_vm_dir(self.test_vms['TEST_VM_1']['name']))
Exemple #2
0
    def test_delete(self, storage_type):
        """Test the deletion of a VM through the argument parser"""
        # Create Virtual machine
        self.create_vm('TEST_VM_1', storage_type)

        # Remove VM using parser
        self.parser.parse_arguments('delete %s --delete-data' % self.test_vms['TEST_VM_1']['name'])

        # Ensure VM has been deleted
        self.assertFalse(self.vm_factory.check_exists(self.test_vms['TEST_VM_1']['name']))

        # Ensure that VM directory does not exist
        self.assertFalse(os.path.exists(
            VirtualMachine._get_vm_dir(self.test_vms['TEST_VM_1']['name'])
        ))
 def get_config_path(vm_name):
     """Provides the path of the VM-spefic configuration file"""
     from mcvirt.virtual_machine.virtual_machine import VirtualMachine
     return ('%s/config.json' % VirtualMachine._get_vm_dir(vm_name))
Exemple #4
0
 def get_config_path(vm_name):
     """Provides the path of the VM-spefic configuration file"""
     from mcvirt.virtual_machine.virtual_machine import VirtualMachine
     return ('%s/config.json' % VirtualMachine._get_vm_dir(vm_name))
Exemple #5
0
    def _create(self,
                name,
                cpu_cores,
                memory_allocation,
                hard_drives=None,
                network_interfaces=None,
                node=None,
                available_nodes=None,
                storage_type=None,
                hard_drive_driver=None,
                graphics_driver=None,
                modification_flags=None):
        """Create a VM and returns the virtual_machine object for it"""
        network_interfaces = [] if network_interfaces is None else network_interfaces
        hard_drives = [] if hard_drives is None else hard_drives
        available_nodes = [] if available_nodes is None else available_nodes
        modification_flags = [] if modification_flags is None else modification_flags

        self.checkName(name)
        ArgumentValidator.validate_positive_integer(cpu_cores)
        ArgumentValidator.validate_positive_integer(memory_allocation)
        for hard_drive in hard_drives:
            ArgumentValidator.validate_positive_integer(hard_drive)
        if network_interfaces:
            for network_interface in network_interfaces:
                ArgumentValidator.validate_network_name(network_interface)
        if node is not None:
            ArgumentValidator.validate_hostname(node)
        for available_node in available_nodes:
            ArgumentValidator.validate_hostname(available_node)
        assert storage_type in [None] + [
            storage_type_itx.__name__ for storage_type_itx in
            self._get_registered_object('hard_drive_factory').STORAGE_TYPES
        ]
        if hard_drive_driver is not None:
            HardDriveDriver[hard_drive_driver]

        # If no graphics driver has been specified, set it to the default
        if graphics_driver is None:
            graphics_driver = self.DEFAULT_GRAPHICS_DRIVER

        # Check the driver name is valid
        self.check_graphics_driver(graphics_driver)

        # Ensure the cluster has not been ignored, as VMs cannot be created with MCVirt running
        # in this state
        if self._cluster_disabled:
            raise ClusterNotInitialisedException(
                'VM cannot be created whilst the cluster' +
                ' is not initialised')

        # Determine if VM already exists
        if self.check_exists(name):
            raise VmAlreadyExistsException('Error: VM already exists')

        # If a node has not been specified, assume the local node
        if node is None:
            node = get_hostname()

        # If Drbd has been chosen as a storage type, ensure it is enabled on the node
        node_drbd = self._get_registered_object('node_drbd')
        if storage_type == 'Drbd' and not node_drbd.is_enabled():
            raise DrbdNotEnabledOnNode('Drbd is not enabled on this node')

        # Create directory for VM on the local and remote nodes
        if os_path_exists(VirtualMachine._get_vm_dir(name)):
            raise VmDirectoryAlreadyExistsException(
                'Error: VM directory already exists')

        # If available nodes has not been passed, assume the local machine is the only
        # available node if local storage is being used. Use the machines in the cluster
        # if Drbd is being used
        cluster_object = self._get_registered_object('cluster')
        all_nodes = cluster_object.get_nodes(return_all=True)
        all_nodes.append(get_hostname())

        if len(available_nodes) == 0:
            if storage_type == 'Drbd':
                # If the available nodes are not specified, use the
                # nodes in the cluster
                available_nodes = all_nodes
            else:
                # For local VMs, only use the local node as the available nodes
                available_nodes = [get_hostname()]

        # If there are more than the maximum number of Drbd machines in the cluster,
        # add an option that forces the user to specify the nodes for the Drbd VM
        # to be added to
        if storage_type == 'Drbd' and len(
                available_nodes) != node_drbd.CLUSTER_SIZE:
            raise InvalidNodesException('Exactly %i nodes must be specified' %
                                        node_drbd.CLUSTER_SIZE)

        for check_node in available_nodes:
            if check_node not in all_nodes:
                raise NodeDoesNotExistException('Node \'%s\' does not exist' %
                                                check_node)

        if get_hostname() not in available_nodes and self._is_cluster_master:
            raise InvalidNodesException(
                'One of the nodes must be the local node')

        # Check whether the hard drives can be created.
        if self._is_cluster_master:
            hard_drive_factory = self._get_registered_object(
                'hard_drive_factory')
            for hard_drive_size in hard_drives:
                hard_drive_factory.ensure_hdd_valid(
                    hard_drive_size, storage_type, [
                        node_itx for node_itx in available_nodes
                        if node_itx != get_hostname()
                    ])

        # Create directory for VM
        makedirs(VirtualMachine._get_vm_dir(name))

        # Add VM to MCVirt configuration
        def updateMCVirtConfig(config):
            config['virtual_machines'].append(name)

        MCVirtConfig().update_config(
            updateMCVirtConfig,
            'Adding new VM \'%s\' to global MCVirt configuration' % name)

        # Create VM configuration file
        VirtualMachineConfig.create(name, available_nodes, cpu_cores,
                                    memory_allocation, graphics_driver)

        # Add VM to remote nodes
        if self._is_cluster_master:

            def remote_command(remote_connection):
                virtual_machine_factory = remote_connection.get_connection(
                    'virtual_machine_factory')
                virtual_machine_factory.create(
                    name=name,
                    memory_allocation=memory_allocation,
                    cpu_cores=cpu_cores,
                    node=node,
                    available_nodes=available_nodes,
                    modification_flags=modification_flags)

            cluster_object.run_remote_command(callback_method=remote_command)

        # Obtain an object for the new VM, to use to create disks/network interfaces
        vm_object = self.getVirtualMachineByName(name)
        vm_object.get_config_object().gitAdd('Created VM \'%s\'' %
                                             vm_object.get_name())

        if node == get_hostname():
            # Register VM with LibVirt. If MCVirt has not been initialised on this node,
            # do not set the node in the VM configuration, as the change can't be
            # replicated to remote nodes
            vm_object._register(set_node=self._is_cluster_master)
        elif self._is_cluster_master:
            # If MCVirt has been initialised on this node and the local machine is
            # not the node that the VM will be registered on, set the node on the VM
            vm_object._setNode(node)

        if self._is_cluster_master:
            # Create disk images
            hard_drive_factory = self._get_registered_object(
                'hard_drive_factory')
            for hard_drive_size in hard_drives:
                hard_drive_factory.create(vm_object=vm_object,
                                          size=hard_drive_size,
                                          storage_type=storage_type,
                                          driver=hard_drive_driver)

            # If any have been specified, add a network configuration for each of the
            # network interfaces to the domain XML
            network_adapter_factory = self._get_registered_object(
                'network_adapter_factory')
            network_factory = self._get_registered_object('network_factory')
            if network_interfaces is not None:
                for network in network_interfaces:
                    network_object = network_factory.get_network_by_name(
                        network)
                    network_adapter_factory.create(vm_object, network_object)

            # Add modification flags
            vm_object._update_modification_flags(add_flags=modification_flags)

        return vm_object
Exemple #6
0
    def _create(self, name, cpu_cores, memory_allocation, hard_drives=[],
                network_interfaces=[], node=None, available_nodes=[], storage_type=None,
                hard_drive_driver=None):
        """Creates a VM and returns the virtual_machine object for it"""
        self.checkName(name)
        ArgumentValidator.validate_positive_integer(cpu_cores)
        ArgumentValidator.validate_positive_integer(memory_allocation)
        for hard_drive in hard_drives:
            ArgumentValidator.validate_positive_integer(hard_drive)
        if network_interfaces:
            for network_interface in network_interfaces:
                ArgumentValidator.validate_network_name(network_interface)
        if node is not None:
            ArgumentValidator.validate_hostname(node)
        for available_node in available_nodes:
            ArgumentValidator.validate_hostname(available_node)
        assert storage_type in [None] + [
            storage_type_itx.__name__ for storage_type_itx in self._get_registered_object(
                'hard_drive_factory').STORAGE_TYPES
        ]
        if hard_drive_driver is not None:
            HardDriveDriver[hard_drive_driver]

        # Ensure the cluster has not been ignored, as VMs cannot be created with MCVirt running
        # in this state
        if self._cluster_disabled:
            raise ClusterNotInitialisedException('VM cannot be created whilst the cluster' +
                                                 ' is not initialised')

        # Determine if VM already exists
        if self.check_exists(name):
            raise VmAlreadyExistsException('Error: VM already exists')

        # If a node has not been specified, assume the local node
        if node is None:
            node = get_hostname()

        # If Drbd has been chosen as a storage type, ensure it is enabled on the node
        node_drbd = self._get_registered_object('node_drbd')
        if storage_type == 'Drbd' and not node_drbd.is_enabled():
            raise DrbdNotEnabledOnNode('Drbd is not enabled on this node')

        # Create directory for VM on the local and remote nodes
        if os_path_exists(VirtualMachine._get_vm_dir(name)):
            raise VmDirectoryAlreadyExistsException('Error: VM directory already exists')

        # If available nodes has not been passed, assume the local machine is the only
        # available node if local storage is being used. Use the machines in the cluster
        # if Drbd is being used
        cluster_object = self._get_registered_object('cluster')
        all_nodes = cluster_object.get_nodes(return_all=True)
        all_nodes.append(get_hostname())

        if len(available_nodes) == 0:
            if storage_type == 'Drbd':
                # If the available nodes are not specified, use the
                # nodes in the cluster
                available_nodes = all_nodes
            else:
                # For local VMs, only use the local node as the available nodes
                available_nodes = [get_hostname()]

        # If there are more than the maximum number of Drbd machines in the cluster,
        # add an option that forces the user to specify the nodes for the Drbd VM
        # to be added to
        if storage_type == 'Drbd' and len(available_nodes) != node_drbd.CLUSTER_SIZE:
            raise InvalidNodesException('Exactly two nodes must be specified')

        for check_node in available_nodes:
            if check_node not in all_nodes:
                raise NodeDoesNotExistException('Node \'%s\' does not exist' % check_node)

        if get_hostname() not in available_nodes and self._is_cluster_master:
            raise InvalidNodesException('One of the nodes must be the local node')

        # Create directory for VM
        makedirs(VirtualMachine._get_vm_dir(name))

        # Add VM to MCVirt configuration
        def updateMCVirtConfig(config):
            config['virtual_machines'].append(name)
        MCVirtConfig().update_config(
            updateMCVirtConfig,
            'Adding new VM \'%s\' to global MCVirt configuration' %
            name)

        # Create VM configuration file
        VirtualMachineConfig.create(name, available_nodes, cpu_cores, memory_allocation)

        # Add VM to remote nodes
        if self._is_cluster_master:
            def remote_command(remote_connection):
                virtual_machine_factory = remote_connection.get_connection(
                    'virtual_machine_factory'
                )
                virtual_machine_factory.create(
                    name=name, memory_allocation=memory_allocation, cpu_cores=cpu_cores,
                    node=node, available_nodes=available_nodes
                )
            cluster_object.run_remote_command(callback_method=remote_command)

        # Obtain an object for the new VM, to use to create disks/network interfaces
        vm_object = self.getVirtualMachineByName(name)
        vm_object.get_config_object().gitAdd('Created VM \'%s\'' % vm_object.get_name())

        if node == get_hostname():
            # Register VM with LibVirt. If MCVirt has not been initialised on this node,
            # do not set the node in the VM configuration, as the change can't be
            # replicated to remote nodes
            vm_object._register(set_node=self._is_cluster_master)
        elif self._is_cluster_master:
            # If MCVirt has been initialised on this node and the local machine is
            # not the node that the VM will be registered on, set the node on the VM
            vm_object._setNode(node)

        if self._is_cluster_master:
            # Create disk images
            hard_drive_factory = self._get_registered_object('hard_drive_factory')
            for hard_drive_size in hard_drives:
                hard_drive_factory.create(vm_object=vm_object, size=hard_drive_size,
                                          storage_type=storage_type, driver=hard_drive_driver)

            # If any have been specified, add a network configuration for each of the
            # network interfaces to the domain XML
            network_adapter_factory = self._get_registered_object('network_adapter_factory')
            network_factory = self._get_registered_object('network_factory')
            if network_interfaces is not None:
                for network in network_interfaces:
                    network_object = network_factory.get_network_by_name(network)
                    network_adapter_factory.create(vm_object, network_object)

        return vm_object