def set_as_template(machineguid): """ Set a vmachine as template @param machineguid: guid of the machine @return: vmachine template conversion successful: True|False """ # Do some magic on the storage layer? # This is most likely required as extra security measure # Suppose the template is set back to a real machine # it can be deleted within vmware which should be blocked. # This might also require a storagerouter internal check # to be implemented to discourage volumes from being deleted # when clones were made from it. vmachine = VMachine(machineguid) if vmachine.hypervisor_status == 'RUNNING': raise RuntimeError('vMachine {0} may not be running to set it as vTemplate'.format(vmachine.name)) for disk in vmachine.vdisks: VDiskController.set_as_template(diskguid=disk.guid) vmachine.is_vtemplate = True vmachine.invalidate_dynamics(['snapshots']) vmachine.save()
def set_as_template(machineguid): """ Set a vmachine as template @param machineguid: guid of the machine @return: vmachine template conversion successful: True|False """ # Do some magic on the storage layer? # This is most likely required as extra security measure # Suppose the template is set back to a real machine # it can be deleted within vmware which should be blocked. # This might also require a storagerouter internal check # to be implemented to discourage volumes from being deleted # when clones were made from it. vmachine = VMachine(machineguid) if vmachine.hypervisor_status == 'RUNNING': raise RuntimeError( 'vMachine {0} may not be running to set it as vTemplate'. format(vmachine.name)) for disk in vmachine.vdisks: VDiskController.set_as_template(diskguid=disk.guid) vmachine.is_vtemplate = True vmachine.invalidate_dynamics(['snapshots']) vmachine.save()
def rollback(machineguid, timestamp): """ Rolls back a VM based on a given disk snapshot timestamp :param machineguid: Guid of the machine to rollback :param timestamp: Timestamp to rollback to """ vmachine = VMachine(machineguid) if vmachine.hypervisor_status == 'RUNNING': raise RuntimeError( 'vMachine {0} may not be running to set it as vTemplate'. format(vmachine.name)) snapshots = [ snap for snap in vmachine.snapshots if snap['timestamp'] == timestamp ] if not snapshots: raise ValueError( 'No vmachine snapshots found for timestamp {0}'.format( timestamp)) for disk in vmachine.vdisks: VDiskController.rollback(diskguid=disk.guid, timestamp=timestamp) vmachine.invalidate_dynamics(['snapshots'])
def snapshot(machineguid, label=None, is_consistent=False, timestamp=None, is_automatic=False): """ Snapshot VMachine disks @param machineguid: guid of the machine @param label: label to give the snapshots @param is_consistent: flag indicating the snapshot was consistent or not @param timestamp: override timestamp, if required. Should be a unix timestamp """ timestamp = timestamp if timestamp is not None else time.time() timestamp = str(int(float(timestamp))) metadata = { 'label': label, 'is_consistent': is_consistent, 'timestamp': timestamp, 'machineguid': machineguid, 'is_automatic': is_automatic } machine = VMachine(machineguid) # @todo: we now skip creating a snapshot when a vmachine's disks # is missing a mandatory property: volume_id # subtask will now raise an exception earlier in the workflow for disk in machine.vdisks: if not disk.volume_id: message = 'Missing volume_id on disk {0} - unable to create snapshot for vm {1}'.format( disk.guid, machine.guid) logger.info('Error: {0}'.format(message)) raise RuntimeError(message) snapshots = {} success = True try: for disk in machine.vdisks: snapshots[disk.guid] = VDiskController.create_snapshot( diskguid=disk.guid, metadata=metadata) except Exception as ex: logger.info('Error snapshotting disk {0}: {1}'.format( disk.name, str(ex))) success = False for diskguid, snapshotid in snapshots.iteritems(): VDiskController.delete_snapshot(diskguid=diskguid, snapshotid=snapshotid) logger.info('Create snapshot for vMachine {0}: {1}'.format( machine.name, 'Success' if success else 'Failure')) machine.invalidate_dynamics(['snapshots']) if not success: raise RuntimeError('Failed to snapshot vMachine {0}'.format( machine.name))
def snapshot(machineguid, label=None, is_consistent=False, timestamp=None, is_automatic=False, is_sticky=False): """ Snapshot VMachine disks :param machineguid: guid of the machine :param label: label to give the snapshots :param is_consistent: flag indicating the snapshot was consistent or not :param timestamp: override timestamp, if required. Should be a unix timestamp :param is_automatic: Flag to determine automated snapshots :param is_sticky: Flag indicating the snapshot is not to be deleted automatically """ timestamp = timestamp if timestamp is not None else time.time() timestamp = str(int(float(timestamp))) if is_automatic is True and is_sticky is True: raise ValueError('Snapshot {0} cannot be both automatic and sticky'.format(label)) metadata = {'label': label, 'is_consistent': is_consistent, 'timestamp': timestamp, 'machineguid': machineguid, 'is_automatic': is_automatic, 'is_sticky': is_sticky} machine = VMachine(machineguid) # @todo: we now skip creating a snapshot when a vmachine's disks # is missing a mandatory property: volume_id # sub-task will now raise an exception earlier in the workflow for disk in machine.vdisks: if not disk.volume_id: message = 'Missing volume_id on disk {0} - unable to create snapshot for vm {1}'.format( disk.guid, machine.guid ) VMachineController._logger.info('Error: {0}'.format(message)) raise RuntimeError(message) snapshots = {} success = True for disk in machine.vdisks: try: snapshots[disk.guid] = VDiskController.create_snapshot(diskguid=disk.guid, metadata=metadata) except Exception as ex: VMachineController._logger.info('Error taking snapshot of disk {0}: {1}'.format(disk.name, str(ex))) success = False for diskguid, snapshotid in snapshots.iteritems(): VDiskController.delete_snapshot(diskguid=diskguid, snapshotid=snapshotid) VMachineController._logger.info('Create snapshot for vMachine {0}: {1}'.format( machine.name, 'Success' if success else 'Failure' )) machine.invalidate_dynamics(['snapshots']) if not success: raise RuntimeError('Failed to snapshot vMachine {0}'.format(machine.name))
def delete_snapshot(vmachineguid, timestamp): """ Remove a snapshot from the vmachine @param vmachineguid: Guid of the virtual machine @param timestamp: timestamp of the snapshot """ vmachine = VMachine(vmachineguid) vmachine_snapshots = [snap for snap in vmachine.snapshots if snap['timestamp'] == str(timestamp)] if len(vmachine_snapshots) != 1: raise RuntimeError('Snapshot {0} does not belong to vmachine {1}'.format(timestamp, vmachine.name)) vmachine_snapshot = vmachine_snapshots[0] VMachineController._logger.info('Deleting snapshot {0} from vmachine {1}'.format(timestamp, vmachine.name)) for diskguid, snapshotid in vmachine_snapshot['snapshots'].items(): VDiskController.delete_snapshot(diskguid, snapshotid) VMachineController._logger.info('Deleted snapshot {0}'.format(timestamp)) vmachine.invalidate_dynamics(['snapshots'])
def rollback(machineguid, timestamp): """ Rolls back a VM based on a given disk snapshot timestamp """ vmachine = VMachine(machineguid) if vmachine.hypervisor_status == 'RUNNING': raise RuntimeError('vMachine {0} may not be running to set it as vTemplate'.format( vmachine.name )) snapshots = [snap for snap in vmachine.snapshots if snap['timestamp'] == timestamp] if not snapshots: raise ValueError('No vmachine snapshots found for timestamp {0}'.format(timestamp)) for disk in vmachine.vdisks: VDiskController.rollback(diskguid=disk.guid, timestamp=timestamp) vmachine.invalidate_dynamics(['snapshots'])