def do_encryption(gce_svc, enc_svc_cls, zone, encryptor, encryptor_image, instance_name, instance_config, encrypted_image_disk, network, status_port=ENCRYPTOR_STATUS_PORT): metadata = gce_metadata_from_userdata(instance_config.make_userdata()) log.info('Launching encryptor instance') gce_svc.run_instance(zone=zone, name=encryptor, image=encryptor_image, network=network, disks=[ gce_svc.get_disk(zone, instance_name), gce_svc.get_disk(zone, encrypted_image_disk) ], metadata=metadata) try: enc_svc = enc_svc_cls([gce_svc.get_instance_ip(encryptor, zone)], port=status_port) wait_for_encryptor_up(enc_svc, Deadline(600)) wait_for_encryption(enc_svc) except Exception as e: f = gce_svc.write_serial_console_file(zone, encryptor) if f: log.info('Encryption failed. Writing console to %s' % f) raise e retry(function=gce_svc.delete_instance, on=[httplib.BadStatusLine, socket.error, errors.HttpError])(zone, encryptor)
def do_encryption(gce_svc, enc_svc_cls, zone, encryptor, encryptor_image, instance_name, instance_config, encrypted_image_disk, network, status_port=ENCRYPTOR_STATUS_PORT): metadata = gce_metadata_from_userdata(instance_config.make_userdata()) log.info('Launching encryptor instance') gce_svc.run_instance(zone=zone, name=encryptor, image=encryptor_image, network=network, disks=[gce_svc.get_disk(zone, instance_name), gce_svc.get_disk(zone, encrypted_image_disk)], metadata=metadata) try: enc_svc = enc_svc_cls([gce_svc.get_instance_ip(encryptor, zone)], port=status_port) wait_for_encryptor_up(enc_svc, Deadline(600)) wait_for_encryption(enc_svc) except Exception as e: f = gce_svc.write_serial_console_file(zone, encryptor) if f: log.info('Encryption failed. Writing console to %s' % f) raise e retry(function=gce_svc.delete_instance, on=[httplib.BadStatusLine, socket.error, errors.HttpError])(zone, encryptor)
def test_encryption_progress_timeout(self): class NoProgressService(encryptor_service.BaseEncryptorService): def __init__(self): super(NoProgressService, self).__init__('localhost', 80) def is_encryptor_up(self): return True def get_status(self): return { 'state': encryptor_service.ENCRYPT_ENCRYPTING, 'percent_complete': 0 } with self.assertRaises(encryptor_service.EncryptionError): encryptor_service.wait_for_encryption(NoProgressService(), progress_timeout=0.100)
def test_unsupported_guest(self): class UnsupportedGuestService(encryptor_service.BaseEncryptorService): def __init__(self): super(UnsupportedGuestService, self).__init__('localhost', 80) def is_encryptor_up(self): return True def get_status(self): return { 'state': encryptor_service.ENCRYPT_FAILED, 'failure_code': encryptor_service.FAILURE_CODE_UNSUPPORTED_GUEST, 'percent_complete': 0 } with self.assertRaises(encryptor_service.UnsupportedGuestError): encryptor_service.wait_for_encryption(UnsupportedGuestService())
def test_encryption_progress_timeout(self): class NoProgressService(encryptor_service.BaseEncryptorService): def __init__(self): super(NoProgressService, self).__init__('localhost', 80) def is_encryptor_up(self): return True def get_status(self): return { 'state': encryptor_service.ENCRYPT_ENCRYPTING, 'percent_complete': 0 } with self.assertRaises(encryptor_service.EncryptionError): encryptor_service.wait_for_encryption( NoProgressService(), progress_timeout=0.100 )
def snapshot_encrypted_instance(aws_svc, enc_svc_cls, encryptor_instance, encryptor_image, image_id=None, vol_type='', iops=None, legacy=False, save_encryptor_logs=True, status_port=encryptor_service.ENCRYPTOR_STATUS_PORT): # First wait for encryption to complete host_ips = [] if encryptor_instance.ip_address: host_ips.append(encryptor_instance.ip_address) if encryptor_instance.private_ip_address: host_ips.append(encryptor_instance.private_ip_address) log.info('Adding %s to NO_PROXY environment variable' % encryptor_instance.private_ip_address) if os.environ.get('NO_PROXY'): os.environ['NO_PROXY'] += "," + \ encryptor_instance.private_ip_address else: os.environ['NO_PROXY'] = encryptor_instance.private_ip_address enc_svc = enc_svc_cls(host_ips, port=status_port) try: log.info('Waiting for encryption service on %s (port %s on %s)', encryptor_instance.id, enc_svc.port, ', '.join(host_ips)) encryptor_service.wait_for_encryptor_up(enc_svc, Deadline(600)) log.info('Creating encrypted root drive.') encryptor_service.wait_for_encryption(enc_svc) except (BracketError, encryptor_service.EncryptionError) as e: # Stop the encryptor instance, to make the console log available. stop_and_wait(aws_svc, encryptor_instance.id) log_exception_console(aws_svc, e, encryptor_instance.id) if save_encryptor_logs: log.info('Saving logs from encryptor instance in snapshot') log_snapshot = snapshot_log_volume(aws_svc, encryptor_instance.id) log.info('Encryptor logs saved in snapshot %(snapshot_id)s. ' 'Run `brkt share-logs --region %(region)s ' '--snapshot-id %(snapshot_id)s` ' 'to share this snapshot with Bracket support' % {'snapshot_id': log_snapshot.id, 'region': aws_svc.region}) raise log.info('Encrypted root drive is ready.') # The encryptor instance may modify its volume attachments while running, # so we update the encryptor instance's local attributes before reading # them. encryptor_instance = aws_svc.get_instance(encryptor_instance.id) encryptor_bdm = encryptor_instance.block_device_mapping # Stop the encryptor instance. log.info('Stopping encryptor instance %s', encryptor_instance.id) aws_svc.stop_instance(encryptor_instance.id) wait_for_instance(aws_svc, encryptor_instance.id, state='stopped') description = DESCRIPTION_SNAPSHOT % {'image_id': image_id} # Set up new Block Device Mappings log.debug('Creating block device mapping') new_bdm = BlockDeviceMapping() if not vol_type or vol_type == '': vol_type = 'gp2' # Snapshot volumes. if encryptor_image.virtualization_type == 'paravirtual': snap_guest = aws_svc.create_snapshot( encryptor_bdm['/dev/sda5'].volume_id, name=NAME_ENCRYPTED_ROOT_SNAPSHOT, description=description ) snap_bsd = aws_svc.create_snapshot( encryptor_bdm['/dev/sda2'].volume_id, name=NAME_METAVISOR_ROOT_SNAPSHOT, description=description ) snap_log = aws_svc.create_snapshot( encryptor_bdm['/dev/sda3'].volume_id, name=NAME_METAVISOR_LOG_SNAPSHOT, description=description ) log.info( 'Creating snapshots for the new encrypted AMI: %s, %s, %s', snap_guest.id, snap_bsd.id, snap_log.id) wait_for_snapshots( aws_svc, snap_guest.id, snap_bsd.id, snap_log.id) if vol_type is None: vol_type = "gp2" dev_guest_root = EBSBlockDeviceType(volume_type=vol_type, snapshot_id=snap_guest.id, iops=iops, delete_on_termination=True) mv_root_id = encryptor_bdm['/dev/sda1'].volume_id dev_mv_root = EBSBlockDeviceType(volume_type='gp2', snapshot_id=snap_bsd.id, delete_on_termination=True) dev_log = EBSBlockDeviceType(volume_type='gp2', snapshot_id=snap_log.id, delete_on_termination=True) new_bdm['/dev/sda2'] = dev_mv_root new_bdm['/dev/sda3'] = dev_log new_bdm['/dev/sda5'] = dev_guest_root else: # HVM instance type snap_guest = aws_svc.create_snapshot( encryptor_bdm['/dev/sdg'].volume_id, name=NAME_ENCRYPTED_ROOT_SNAPSHOT, description=description ) log.info( 'Creating snapshots for the new encrypted AMI: %s' % ( snap_guest.id) ) wait_for_snapshots(aws_svc, snap_guest.id) dev_guest_root = EBSBlockDeviceType(volume_type=vol_type, snapshot_id=snap_guest.id, iops=iops, delete_on_termination=True) mv_root_id = encryptor_bdm['/dev/sda1'].volume_id new_bdm['/dev/sdf'] = dev_guest_root if not legacy: log.info("Detaching new guest root %s" % (mv_root_id,)) aws_svc.detach_volume( mv_root_id, instance_id=encryptor_instance.id, force=True ) aws_service.wait_for_volume(aws_svc, mv_root_id) aws_svc.create_tags( mv_root_id, name=NAME_METAVISOR_ROOT_VOLUME) if image_id: log.debug('Getting image %s', image_id) guest_image = aws_svc.get_image(image_id) if guest_image is None: raise BracketError("Can't find image %s" % image_id) # Propagate any ephemeral drive mappings to the soloized image guest_bdm = guest_image.block_device_mapping for key in guest_bdm.keys(): guest_vol = guest_bdm[key] if guest_vol.ephemeral_name: log.info('Propagating block device mapping for %s at %s' % (guest_vol.ephemeral_name, key)) new_bdm[key] = guest_vol return mv_root_id, new_bdm
def update_gce_image(gce_svc, enc_svc_cls, image_id, encryptor_image, encrypted_image_name, zone, instance_config, keep_encryptor=False, image_file=None, image_bucket=None, network=None, status_port=ENCRYPTOR_STATUS_PORT): snap_created = None try: # create image from file in GCS bucket log.info('Retrieving encryptor image from GCS bucket') if not encryptor_image: encryptor_image = gce_svc.get_latest_encryptor_image(zone, image_bucket, image_file=image_file) else: # Keep user provided encryptor image keep_encryptor = True instance_name = 'brkt-updater-' + gce_svc.get_session_id() updater = instance_name + '-metavisor' encrypted_image_disk = instance_name + '-guest' # Create disk from encrypted guest snapshot. This disk # won't be altered. It will be re-snapshotted and paired # with the new encryptor image. gce_svc.disk_from_snapshot(zone, image_id, encrypted_image_disk) gce_svc.wait_for_disk(zone, encrypted_image_disk) log.info("Creating snapshot of encrypted image disk") gce_svc.create_snapshot(zone, encrypted_image_disk, encrypted_image_name) snap_created = True log.info("Launching encrypted updater") instance_config.brkt_config['solo_mode'] = 'updater' user_data = gce_metadata_from_userdata(instance_config.make_userdata()) gce_svc.run_instance(zone, updater, encryptor_image, network=network, disks=[], metadata=user_data) enc_svc = enc_svc_cls([gce_svc.get_instance_ip(updater, zone)], port=status_port) # wait for updater to finish and guest root disk wait_for_encryptor_up(enc_svc, Deadline(600)) try: wait_for_encryption(enc_svc) except: raise # delete updater instance log.info('Deleting updater instance') gce_svc.delete_instance(zone, updater) # wait for updater root disk gce_svc.wait_for_detach(zone, updater) # create image from mv root disk and snapshot # encrypted guest root disk log.info("Creating updated metavisor image") gce_svc.create_gce_image_from_disk(zone, encrypted_image_name, updater) gce_svc.wait_image(encrypted_image_name) gce_svc.wait_snapshot(encrypted_image_name) except: f = gce_svc.write_serial_console_file(zone, updater) if f: log.info('Update failed. Writing console to %s' % f) log.info("Update failed. Cleaning up") if snap_created: gce_svc.delete_snapshot(encrypted_image_name) gce_svc.cleanup(zone, encryptor_image, keep_encryptor) raise finally: gce_svc.cleanup(zone, encryptor_image, keep_encryptor) return encrypted_image_name
def test_encryption_fails(self): svc = FailedEncryptionService('192.168.1.1') with self.assertRaisesRegexp( encryptor_service.EncryptionError, 'Encryption failed'): encryptor_service.wait_for_encryption(svc)
def update_gce_image(gce_svc, enc_svc_cls, image_id, encryptor_image, encrypted_image_name, zone, instance_config, keep_encryptor=False, image_file=None, image_bucket=None, network=None, status_port=ENCRYPTOR_STATUS_PORT): snap_created = None try: # create image from file in GCS bucket log.info('Retrieving encryptor image from GCS bucket') if not encryptor_image: encryptor_image = gce_svc.get_latest_encryptor_image( zone, image_bucket, image_file=image_file) else: # Keep user provided encryptor image keep_encryptor = True instance_name = 'brkt-updater-' + gce_svc.get_session_id() updater = instance_name + '-metavisor' encrypted_image_disk = instance_name + '-guest' # Create disk from encrypted guest snapshot. This disk # won't be altered. It will be re-snapshotted and paired # with the new encryptor image. gce_svc.disk_from_snapshot(zone, image_id, encrypted_image_disk) gce_svc.wait_for_disk(zone, encrypted_image_disk) log.info("Creating snapshot of encrypted image disk") gce_svc.create_snapshot(zone, encrypted_image_disk, encrypted_image_name) snap_created = True log.info("Launching encrypted updater") instance_config.brkt_config['solo_mode'] = 'updater' user_data = gce_metadata_from_userdata(instance_config.make_userdata()) gce_svc.run_instance(zone, updater, encryptor_image, network=network, disks=[], metadata=user_data) enc_svc = enc_svc_cls([gce_svc.get_instance_ip(updater, zone)], port=status_port) # wait for updater to finish and guest root disk wait_for_encryptor_up(enc_svc, Deadline(600)) try: wait_for_encryption(enc_svc) except: raise # delete updater instance log.info('Deleting updater instance') gce_svc.delete_instance(zone, updater) # wait for updater root disk gce_svc.wait_for_detach(zone, updater) # create image from mv root disk and snapshot # encrypted guest root disk log.info("Creating updated metavisor image") gce_svc.create_gce_image_from_disk(zone, encrypted_image_name, updater) gce_svc.wait_image(encrypted_image_name) gce_svc.wait_snapshot(encrypted_image_name) except: f = gce_svc.write_serial_console_file(zone, updater) if f: log.info('Update failed. Writing console to %s' % f) log.info("Update failed. Cleaning up") if snap_created: gce_svc.delete_snapshot(encrypted_image_name) gce_svc.cleanup(zone, encryptor_image, keep_encryptor) raise finally: gce_svc.cleanup(zone, encryptor_image, keep_encryptor) return encrypted_image_name
def update_ami(aws_svc, encrypted_ami, updater_ami, encrypted_ami_name, subnet_id=None, security_group_ids=None, enc_svc_class=encryptor_service.EncryptorService, guest_instance_type='m3.medium', updater_instance_type='m3.medium', instance_config=None, status_port=encryptor_service.ENCRYPTOR_STATUS_PORT): encrypted_guest = None updater = None mv_root_id = None temp_sg_id = None if instance_config is None: instance_config = InstanceConfig() try: guest_image = aws_svc.get_image(encrypted_ami) # Step 1. Launch encrypted guest AMI # Use 'updater' mode to avoid chain loading the guest # automatically. We just want this AMI/instance up as the # base to create a new AMI and preserve license # information embedded in the guest AMI log.info("Launching encrypted guest/updater") instance_config.brkt_config['solo_mode'] = 'updater' instance_config.brkt_config['status_port'] = status_port encrypted_guest = aws_svc.run_instance( encrypted_ami, instance_type=guest_instance_type, ebs_optimized=False, subnet_id=subnet_id, user_data=json.dumps(instance_config.brkt_config)) aws_svc.create_tags( encrypted_guest.id, name=NAME_GUEST_CREATOR, description=DESCRIPTION_GUEST_CREATOR % {'image_id': encrypted_ami} ) # Run updater in same zone as guest so we can swap volumes user_data = instance_config.make_userdata() compressed_user_data = gzip_user_data(user_data) # If the user didn't specify a security group, create a temporary # security group that allows brkt-cli to get status from the updater. run_instance = aws_svc.run_instance if not security_group_ids: vpc_id = None if subnet_id: subnet = aws_svc.get_subnet(subnet_id) vpc_id = subnet.vpc_id temp_sg_id = create_encryptor_security_group( aws_svc, vpc_id=vpc_id, status_port=status_port).id security_group_ids = [temp_sg_id] # Wrap with a retry, to handle eventual consistency issues with # the newly-created group. run_instance = aws_svc.retry( aws_svc.run_instance, error_code_regexp='InvalidGroup\.NotFound' ) updater = run_instance( updater_ami, instance_type=updater_instance_type, user_data=compressed_user_data, ebs_optimized=False, subnet_id=subnet_id, placement=encrypted_guest.placement, security_group_ids=security_group_ids) aws_svc.create_tags( updater.id, name=NAME_METAVISOR_UPDATER, description=DESCRIPTION_METAVISOR_UPDATER, ) wait_for_instance(aws_svc, encrypted_guest.id, state="running") log.info("Launched guest: %s Updater: %s" % (encrypted_guest.id, updater.id) ) # Step 2. Wait for the updater to finish and stop the instances aws_svc.stop_instance(encrypted_guest.id) updater = wait_for_instance(aws_svc, updater.id, state="running") host_ips = [] if updater.ip_address: host_ips.append(updater.ip_address) if updater.private_ip_address: host_ips.append(updater.private_ip_address) log.info('Adding %s to NO_PROXY environment variable' % updater.private_ip_address) if os.environ.get('NO_PROXY'): os.environ['NO_PROXY'] += "," + \ updater.private_ip_address else: os.environ['NO_PROXY'] = updater.private_ip_address enc_svc = enc_svc_class(host_ips, port=status_port) log.info('Waiting for updater service on %s (port %s on %s)', updater.id, enc_svc.port, ', '.join(host_ips)) wait_for_encryptor_up(enc_svc, Deadline(600)) try: wait_for_encryption(enc_svc) except Exception as e: # Stop the updater instance, to make the console log available. encrypt_ami.stop_and_wait(aws_svc, updater.id) log_exception_console(aws_svc, e, updater.id) raise aws_svc.stop_instance(updater.id) encrypted_guest = wait_for_instance( aws_svc, encrypted_guest.id, state="stopped") updater = wait_for_instance(aws_svc, updater.id, state="stopped") guest_bdm = encrypted_guest.block_device_mapping updater_bdm = updater.block_device_mapping # Step 3. Detach old BSD drive(s) and delete from encrypted guest if guest_image.virtualization_type == 'paravirtual': d_list = ['/dev/sda1', '/dev/sda2', '/dev/sda3'] else: d_list = [encrypted_guest.root_device_name] for d in d_list: log.info("Detaching old metavisor disk: %s from %s" % (guest_bdm[d].volume_id, encrypted_guest.id)) aws_svc.detach_volume(guest_bdm[d].volume_id, instance_id=encrypted_guest.id, force=True ) aws_svc.delete_volume(guest_bdm[d].volume_id) # Step 4. Snapshot MV volume(s) log.info("Creating snapshots") if guest_image.virtualization_type == 'paravirtual': description = DESCRIPTION_SNAPSHOT % {'image_id': updater.id} snap_root = aws_svc.create_snapshot( updater_bdm['/dev/sda2'].volume_id, name=NAME_METAVISOR_ROOT_SNAPSHOT, description=description ) snap_log = aws_svc.create_snapshot( updater_bdm['/dev/sda3'].volume_id, name=NAME_METAVISOR_LOG_SNAPSHOT, description=description ) wait_for_snapshots(aws_svc, snap_root.id, snap_log.id) dev_root = EBSBlockDeviceType(volume_type='gp2', snapshot_id=snap_root.id, delete_on_termination=True) dev_log = EBSBlockDeviceType(volume_type='gp2', snapshot_id=snap_log.id, delete_on_termination=True) guest_bdm['/dev/sda2'] = dev_root guest_bdm['/dev/sda3'] = dev_log # Use updater as base instance for create_image boot_snap_name = NAME_METAVISOR_GRUB_SNAPSHOT root_device_name = updater.root_device_name guest_root = '/dev/sda5' d_list.append(guest_root) else: # Use guest_instance as base instance for create_image boot_snap_name = NAME_METAVISOR_ROOT_SNAPSHOT root_device_name = guest_image.root_device_name guest_root = '/dev/sdf' d_list.append(guest_root) # Preserve volume type for any additional attached volumes for d in guest_bdm.keys(): if d not in d_list: log.debug("Preserving volume type for disk %s", d) vol_id = guest_bdm[d].volume_id vol = aws_svc.get_volume(vol_id) guest_bdm[d].volume_type = vol.type # Step 5. Move new MV boot disk to base instance log.info("Detach boot volume from %s" % (updater.id,)) mv_root_id = updater_bdm['/dev/sda1'].volume_id aws_svc.detach_volume(mv_root_id, instance_id=updater.id, force=True ) # Step 6. Attach new boot disk to guest instance log.info("Attaching new metavisor boot disk: %s to %s" % (mv_root_id, encrypted_guest.id) ) aws_svc.attach_volume(mv_root_id, encrypted_guest.id, root_device_name) encrypted_guest = encrypt_ami.wait_for_volume_attached( aws_svc, encrypted_guest.id, root_device_name) guest_bdm[root_device_name] = \ encrypted_guest.block_device_mapping[root_device_name] guest_bdm[root_device_name].delete_on_termination = True guest_bdm[root_device_name].volume_type = 'gp2' guest_root_vol_id = guest_bdm[guest_root].volume_id guest_root_vol = aws_svc.get_volume(guest_root_vol_id) guest_bdm[guest_root].volume_type = guest_root_vol.type # Step 7. Create new AMI. Preserve billing/license info log.info("Creating new AMI") ami = aws_svc.create_image( encrypted_guest.id, encrypted_ami_name, description=guest_image.description, no_reboot=True, block_device_mapping=guest_bdm ) wait_for_image(aws_svc, ami) image = aws_svc.get_image(ami, retry=True) aws_svc.create_tags( image.block_device_mapping[root_device_name].snapshot_id, name=boot_snap_name, ) aws_svc.create_tags( image.block_device_mapping[guest_root].snapshot_id, name=NAME_ENCRYPTED_ROOT_SNAPSHOT, ) aws_svc.create_tags(ami) return ami finally: instance_ids = set() volume_ids = set() sg_ids = set() if encrypted_guest: instance_ids.add(encrypted_guest.id) if updater: instance_ids.add(updater.id) if mv_root_id: volume_ids.add(mv_root_id) if temp_sg_id: sg_ids.add(temp_sg_id) clean_up(aws_svc, instance_ids=instance_ids, volume_ids=volume_ids, security_group_ids=sg_ids)
def create_ovf_image_from_mv_vm(vc_swc, enc_svc_cls, vm, guest_vmdk, vm_name=None, create_ovf=False, create_ova=False, target_path=None, image_name=None, ovftool_path=None, user_data_str=None, serial_port_file_name=None, status_port=ENCRYPTOR_STATUS_PORT): try: mv_vm_name = None # Reconfigure VM with more CPUs and memory vc_swc.reconfigure_vm_cpu_ram(vm) # Reconfigure VM with serial port if serial_port_file_name is not None: vc_swc.add_serial_port_to_file(vm, serial_port_file_name) # Add datastore path to the guest vmdk guest_vmdk_path = vc_swc.get_datastore_path(guest_vmdk) # Attach guest vmdk vc_swc.add_disk(vm, filename=guest_vmdk_path, unit_number=2) # Attach empty disk size = vc_swc.get_disk_size(vm, 2) encrypted_guest_size = (2 * size) + (1024*1024) vc_swc.add_disk(vm, disk_size=encrypted_guest_size, unit_number=1) # Power on the VM and wait for encryption vc_swc.power_on(vm) # Send user data vc_swc.send_userdata(vm, user_data_str) ip_addr = vc_swc.get_ip_address(vm) log.info("VM ip address is %s", ip_addr) # disconnect from vcenter mv_vm_name = vc_swc.get_vm_name(vm) vc_swc.disconnect() # wait for encryption to complete host_ips = [ip_addr] enc_svc = enc_svc_cls(host_ips, port=status_port) wait_for_encryptor_up(enc_svc, Deadline(600)) wait_for_encryption(enc_svc) # reconnect to vcenter try: vc_swc.connect() except: log.error("Failed to re-connect to vCenter after encryption. " "Please cleanup VM %s manually.", mv_vm_name) raise vm = vc_swc.find_vm(mv_vm_name) # detach unencrypted guest root vc_swc.power_off(vm) vc_swc.detach_disk(vm, unit_number=2) # detach serial port if serial_port_file_name is not None: vc_swc.delete_serial_port_to_file(vm, serial_port_file_name) if ((create_ovf is True) or (create_ova is True)): log.info("Creating images") if target_path is None: raise Exception("Cannot create ova/ovf as target path is None") ovf = vc_swc.export_to_ovf(vm, target_path, ovf_name=image_name) if create_ova is True: if ovftool_path is not None: ova = vc_swc.convert_ovf_to_ova(ovftool_path, ovf) print(ova) else: print(ovf) else: # clone the vm to create template if vc_swc.is_esx_host() is False: log.info("Creating the template VM") template_vm = vc_swc.clone_vm(vm, vm_name=vm_name, template=True) print(vc_swc.get_vm_name(template_vm)) except EncryptionError as e: log.exception("Failed to encrypt the image with error %s", e) try: vc_swc.connect() vm = vc_swc.find_vm(mv_vm_name) vc_swc.power_off(vm) vc_swc.detach_disk(vm, unit_number=2) except: log.error("Failed to detach guest vmdk after encryption failure. " "Please detach guest vmdk manually before cleaning " "up VM %s.", mv_vm_name) vc_swc.set_teardown(True) raise except Exception as e: log.exception("Failed to encrypt the image with error %s", e) raise finally: if vc_swc.no_teardown is False: if (vc_swc.is_esx_host() is True and create_ovf is False and create_ova is False): # Do not clean up encryptor VM as it will be # used as the clone VM log.info("Encrypted VM is %s", mv_vm_name) else: if vc_swc.connected() is False: try: vc_swc.connect() except: log.error("Failed to re-connect to vCenter after " "encryption. Please cleanup VM %s manually.", mv_vm_name) raise vm = None if mv_vm_name: vm = vc_swc.find_vm(mv_vm_name) if vm is not None: vc_swc.destroy_vm(vm) log.info("Done")
def update_ovf_image_mv_vm(vc_swc, enc_svc_cls, guest_vm, mv_vm, template_vm_name, target_path, ovf_name, ova_name, ovftool_path, user_data_str, status_port=ENCRYPTOR_STATUS_PORT): try: # Reconfigure VM with more CPUs and memory vc_swc.reconfigure_vm_cpu_ram(mv_vm) # Power on the MV VM and wait for encryption vc_swc.power_on(mv_vm) # Send user data vc_swc.send_userdata(mv_vm, user_data_str) ip_addr = vc_swc.get_ip_address(mv_vm) log.info("MV VM ip address is %s", ip_addr) # wait for encryption to complete host_ips = [ip_addr] enc_svc = enc_svc_cls(host_ips, port=status_port) log.info('Waiting for updater service on port %s on %s', enc_svc.port, ', '.join(host_ips)) wait_for_encryptor_up(enc_svc, Deadline(600)) try: wait_for_encryption(enc_svc) except Exception as e: log.exception("Update failed with error %s", e) raise # Power off the VMs vc_swc.power_off(guest_vm) vc_swc.power_off(mv_vm) # Detach disks from guest_vm guest_old_disk = vc_swc.detach_disk(guest_vm, unit_number=1) mv_old_disk = vc_swc.detach_disk(guest_vm, unit_number=0) # Get the new MV disk new_disk = vc_swc.get_disk(mv_vm, unit_number=0) # Clone and attach new MV disk to guest VM log.info("Cloning Metavisor disk") u_disk_name = vc_swc.clone_disk(new_disk, dest_disk=mv_old_disk) # Add disks to guest VM vc_swc.add_disk(guest_vm, filename=u_disk_name, unit_number=0) vc_swc.add_disk(guest_vm, filename=vc_swc.get_disk_name(guest_old_disk), unit_number=1) if ((ovf_name) or (ova_name)): if(ova_name): ovf_name = ova_name log.info("Creating images") if target_path is None: raise Exception("Cannot create ova/ovf as target path is None") if (ova_name): # delete the old mf file os.remove(os.path.join(target_path, ova_name + ".mf")) # import the new OVF ovf = vc_swc.export_to_ovf(guest_vm, target_path, ovf_name=ovf_name) if ova_name: if ovftool_path is not None: # delete the old ova os.remove(os.path.join(target_path, ova_name + ".ova")) ova = vc_swc.convert_ovf_to_ova(ovftool_path, ovf) print(ova) else: print(ovf) else: # delete the old vm template log.info("Deleting the old template") template_vm = vc_swc.find_vm(template_vm_name) if (template_vm): vc_swc.destroy_vm(template_vm) # clone the vm to create template log.info("Creating the template VM") template_vm = vc_swc.clone_vm(guest_vm, vm_name=template_vm_name, template=True) print(vc_swc.get_vm_name(template_vm)) except Exception as e: log.exception("Failed to update the image with error %s", e) raise finally: vc_swc.destroy_vm(guest_vm) vc_swc.destroy_vm(mv_vm) log.info("Done")
def test_encryption_fails(self): svc = FailedEncryptionService('192.168.1.1') with self.assertRaisesRegexp(encryptor_service.EncryptionError, 'Encryption failed'): encryptor_service.wait_for_encryption(svc)