def _create_system_disk(self): volume_category = self.resource_config.get('is_system_disk') if (not volume_category) or str(volume_category).lower() == "false": return False ctx.logger.info("SmartX create system disk.") target_instance = self.get_related_vm() server_id = target_instance.runtime_properties.get(EXTERNAL_ID) with ComputeHelper(Client(**self.connection_config)) as helper: vm_info = helper.get_vm(server_id) ctx.logger.info( 'Create volume from SmartX successfully. vm_info:{}'.format( vm_info)) volume_id = "" for volume in vm_info.get("disks"): if isinstance( volume, dict) and volume.get("type") == "disk": # system disk volume_id = volume.get("volume_uuid") break if volume_id: with VolumeHelper(Client(**self.connection_config)) as helper: volume_info = helper.get_volume(volume_id) volume_size_byte = volume_info.get( 'size_in_byte') or volume_info.get('size') volume_size = volume_size_byte >> 30 volume_info['size'] = volume_size extra_values = { 'volume': { 'size': volume_size }, 'host_id': target_instance.id } self.save_runtime_properties('volume', volume_info, extra_values) return True
def create(self, **kwargs): if self._create_system_disk(): return volume_category = self.resource_config.get('is_system_disk') if volume_category and str(volume_category).lower() == "true": ctx.logger.info("SmartX doesn't support system disk.") return try: target_instance = self.get_related_vm() server_id = target_instance.runtime_properties.get(EXTERNAL_ID) with ComputeHelper(Client()) as helper: vm_info = helper.get_vm(server_id) with VolumeHelper(Client()) as helper: if self.use_external_resource: volume_id = validate_parameter('resource_id', self.resource_config) ctx.logger.info( 'Use existed SmartX volume: {}.'.format(volume_id)) else: size = int(validate_parameter('size', self.resource_config)) size_in_byte = size << 30 volume_dict = { "name": self.resource_config.get('name') or ctx.instance.id, "size_in_byte": size_in_byte } self.set_optional_values(self.resource_config, volume_dict, optional_keys) ctx.logger.info( 'Creating SmartX volume with parameters: {}'.format( volume_dict)) job_info = helper.create_volume(volume_dict) helper.wait_job(job_info['job_id']) volume_id = self.wait_job(helper, job_info['job_id'], resource_type='KVM_VOLUME') ctx.logger.info('Create volume from SmartX successfully.') volume_info = helper.get_volume(volume_id) self.attach_volume(helper, vm_info, volume_info) extra_values = { 'volume': { 'size': size }, 'host_id': target_instance.id } self.save_runtime_properties('volume', volume_info, extra_values) except Exception as e: raise NonRecoverableError( 'Create volume from SmartX failed: {}.'.format(e))
def custom_detach(self, **kwargs): volume_id = ctx.instance.runtime_properties.get(EXTERNAL_ID) server_id = kwargs.get('server_id') with ComputeHelper(Client()) as helper: vm_info = helper.get_vm(server_id) with VolumeHelper(Client()) as helper: volume_info = helper.get_volume(volume_id) self.detach_volume(helper, vm_info, volume_info)
def custom_attach(self, **kwargs): volume_id = ctx.instance.runtime_properties.get(EXTERNAL_ID) server_id = kwargs.get('server_id') with ComputeHelper(Client()) as helper: vm_info = helper.get_vm(server_id) with VolumeHelper(Client()) as helper: volume_info = helper.get_volume(volume_id) self.attach_volume(helper, vm_info, volume_info) size_in_byte = volume_info.get("size_in_byte") or volume_info.get( "size") size = int(size_in_byte) >> 30 extra_values = {'volume': {'size': size}} self.save_runtime_properties('volume', extra_values=extra_values)
def create(self, **kwargs): # todo: Create new network try: with NetworkHelper(Client()) as helper: network_id = validate_parameter('resource_id', self.resource_config) subnet_id = validate_parameter('subnet_id', self.resource_config) ctx.logger.info( 'Use existed SmartX network: {}, subnet: {}.'.format( network_id, subnet_id)) network_info = helper.get_vds(network_id) subnet_info = helper.get_network(network_id, subnet_id) network_index = ctx.node.name[-1] if ctx.node.name[-1].isdigit( ) else 0 set_runtime_properties('network_index', network_index, ctx.instance) set_runtime_properties('subnet_info', subnet_info, ctx.instance) extra_values = { EXTERNAL_ID: subnet_id, } self.save_runtime_properties('network', network_info, extra_values) except Exception as e: raise NonRecoverableError( 'Create network from SmartX failed: {}.'.format(e))
def resize(self, **kwargs): vm_id = ctx.instance.runtime_properties.get(EXTERNAL_ID) with ComputeHelper(Client()) as helper: vm_state = self.get_status(helper, vm_id) if vm_state != SMARTX_INSTANCE_STATE_STOPPED: ctx.logger.error( "The virtual machine's status should be stopped, current status is:{}" .format(vm_state)) return new_cpu = validate_parameter('cpus', kwargs) new_memory = validate_parameter('memory', kwargs) if (not new_cpu) and (not new_memory): ctx.logger.error( "The param `CPU` and `Memory` is required, received param is:{}" .format(kwargs)) return vm_info = helper.get_vm(vm_id) _cpu = vm_info['cpu'] _params = {'ha': vm_info['ha']} if new_cpu: _cpu['topology']['cores'] = new_cpu _params.update({'vcpu': new_cpu}) _params.update({'cpu': _cpu}) if new_memory: new_memory = new_memory << 20 # memory->Byte _params.update({'memory': new_memory}) job_info = helper.modify_configure(vm_id, _params) ret = self.wait_job(helper, job_info['job_id']) ctx.logger.info("smartx resized result: {}".format(ret)) vm_info = helper.get_vm(vm_id) self.save_runtime_properties('compute', vm_info) ctx.logger.info("smartx resized done")
def reboot(self, **kwargs): vm_id = ctx.instance.runtime_properties.get(EXTERNAL_ID) ctx.logger.info('Rebooting SmartX VM {}.'.format(vm_id)) with ComputeHelper(Client()) as helper: job_info = helper.reboot_vm(vm_id) self.wait_job(helper, job_info['job_id']) ctx.logger.info('SmartX VM {} rebooted.'.format(vm_id))
def update_networks(self): ips = [] vm_id = ctx.instance.runtime_properties.get(EXTERNAL_ID) with ComputeHelper(Client()) as helper: vm = helper.get_vm(vm_id) nics = vm.get('nics', []) if self.use_external_resource: # There is not network connected to instance,instance is external. net_info = { 'ip': nics[0].get('ip_address') or '', 'name': 'PrivateIpAddress' } ctx.instance.runtime_properties['networks'] = {"Network": net_info} ctx.instance.runtime_properties['ip'] = nics[0].get('ip_address') else: # Create by CMP. networks = self.get_networks() runtime_networks = ctx.instance.runtime_properties.get('networks') for network in networks: subnet_info = network.instance.runtime_properties[ 'subnet_info'] for nic in nics: if network.node.properties.get('resource_config').get( 'subnet_id') == nic['vlan_uuid']: subnet_info['ip'] = nic['ip_address'] or '' network_node_id = network.node.id runtime_networks[network_node_id].update(subnet_info) ctx.instance.runtime_properties.update( {'networks': runtime_networks}) for nic in nics: ips.append(nic.get("ip_address")) ctx.instance.runtime_properties['ips'] = ips ctx.instance.update()
def custom_resize(self, **kwargs): volume_id = ctx.instance.runtime_properties.get(EXTERNAL_ID) size = validate_parameter('size', kwargs) size_in_byte = int(size) << 30 data = {'size_in_byte': size_in_byte} if kwargs.get('description'): data['description'] = kwargs['description'] ctx.logger.debug('Resizing volume {} with parameters {}.'.format( volume_id, data)) try: with VolumeHelper(Client()) as helper: volume_info = helper.get_volume(volume_id) volume_name = volume_info.get("name") if not volume_name: ctx.logger.error( 'Resizing volume {} failed. volume_name is required'. format(volume_id)) return data.update({"name": volume_name}) helper.update_volume(volume_id, data) except Exception as e: raise NonRecoverableError('Resize volume {} failed: {}.'.format( volume_id, e)) extra_values = {'volume': {'size': size}} self.save_runtime_properties('volume', extra_values=extra_values) ctx.logger.debug('Resized volume {}'.format(volume_id))
def modify_display_name(self, **kwargs): new_name = validate_parameter(ctx.instance.id, kwargs.get('names', {})) vm_id = ctx.instance.runtime_properties.get(EXTERNAL_ID) ctx.logger.info('Updating name of SmartX VM {}.'.format(vm_id)) with ComputeHelper(Client()) as helper: helper.modify_display_name(vm_id, new_name) ctx.instance.runtime_properties[EXTERNAL_NAME] = new_name ctx.logger.info('Updated name of SmartX VM {}.'.format(vm_id))
def start(self, **kwargs): vm_id = ctx.instance.runtime_properties.get(EXTERNAL_ID) ctx.logger.info('Staring SmartX VM {}.'.format(vm_id)) with ComputeHelper(Client()) as helper: job_info = helper.start_vm(vm_id) self.wait_vm_ready(helper, job_info['job_id'], vm_id) vm = helper.get_vm(vm_id) if not self.use_external_resource: # Create by CMP. self.save_primary_ip(vm) ctx.logger.info('SmartX VM {} started.'.format(vm_id)) self.update_networks()
def stop(self, **kwargs): vm_id = ctx.instance.runtime_properties.get(EXTERNAL_ID) if not vm_id: ctx.logger.warn('Id of vm not found, skip stopping.') return ctx.logger.info('Stopping SmartX VM {}.'.format(vm_id)) with ComputeHelper(Client()) as helper: if not self.get_vm(helper, vm_id): ctx.logger.info( 'SmartX VM:{} is not exist, no need to stop'.format(vm_id)) return job_info = helper.stop_vm(vm_id) self.wait_job(helper, job_info['job_id']) ctx.logger.info('SmartX VM {} stopped.'.format(vm_id))
def create(self, **kwargs): with ComputeHelper(Client()) as helper: if self._create_external_instance(helper): return if self.clone_instance(helper): return data = self._get_instances_params() ctx.logger.info('Creating SmartX VM with parameters: {}'.format( json.dumps(self.hiden_password(data), indent=2))) job_info = helper.create_vm_from_template(data) vm_id = self.wait_job(helper, job_info['job_id']) vm_info = helper.get_vm(vm_id) ctx.logger.info('Create VM from SmartX successfully.') extra_values = {EXTERNAL_HOSTNAME: data['cloud_init']['hostname']} self.save_runtime_properties('compute', vm_info, extra_values)
def delete(self, **kwargs): vm_id = ctx.instance.runtime_properties.get(EXTERNAL_ID) if not vm_id: ctx.logger.warn('Id of vm not found, skip stopping.') return ctx.logger.info('Deleting SmartX VM {}.'.format(vm_id)) with ComputeHelper(Client()) as helper: if not self.get_vm(helper, vm_id): ctx.logger.info( 'SmartX VM:{} is not exist, no need to delete'.format( vm_id)) return data = {'include_volumes': True} job_info = helper.delete_vm(vm_id, json.dumps(data)) self.wait_job(helper, job_info['job_id']) clear_runtime_properties() ctx.logger.info('SmartX VM {} deleted.'.format(vm_id))
def delete(self, **kwargs): volume_id = ctx.instance.runtime_properties.get(EXTERNAL_ID) ctx.logger.info('SmartX volume {} deleted.'.format(volume_id)) if not volume_id: ctx.logger.warn('No SmartX volume id provided.') return try: ctx.logger.info('Deleting SmartX volume {}.'.format(volume_id)) with VolumeHelper(Client()) as helper: volume_info = helper.get_volume(volume_id) target_instance = self.get_related_vm() vm_info = target_instance.runtime_properties.get( 'compute_info') self.detach_volume(helper, vm_info, volume_info) job_info = helper.delete_volume(volume_id) self.wait_job(helper, job_info['job_id']) ctx.logger.info('SmartX volume {} deleted.'.format(volume_id)) clear_runtime_properties() except Exception as e: raise NonRecoverableError( 'Delete SmartX volume {} failed: {}'.format(volume_id, e))