def _connect(self): connection_info = self._connection_info host = connection_info["ip"] port = connection_info.get("port", 5986) username = connection_info["username"] password = connection_info.get("password") cert_pem = connection_info.get("cert_pem") cert_key_pem = connection_info.get("cert_key_pem") url = "https://%s:%s/wsman" % (host, port) LOG.info("Connection info: %s", str(connection_info)) LOG.info("Waiting for connectivity on host: %(host)s:%(port)s", { "host": host, "port": port }) utils.wait_for_port_connectivity(host, port) self._event_manager.progress_update( "Connecting to WinRM host: %(host)s:%(port)s" % { "host": host, "port": port }) conn = wsman.WSManConnection() conn.connect(url=url, username=username, password=password, cert_pem=cert_pem, cert_key_pem=cert_key_pem) self._conn = conn
def _connect(self, connection_info): ip = connection_info["ip"] port = connection_info.get("port", 22) username = connection_info["username"] pkey = connection_info.get("pkey") password = connection_info.get("password") LOG.info("Waiting for connectivity on host: %(ip)s:%(port)s", { "ip": ip, "port": port }) utils.wait_for_port_connectivity(ip, port) self._event_manager.progress_update( "Connecting to SSH host: %(ip)s:%(port)s" % { "ip": ip, "port": port }) ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(hostname=ip, port=port, username=username, pkey=pkey, password=password) self._ssh = ssh
def _connect(self): connection_info = self._connection_info ip = connection_info["ip"] port = connection_info.get("port", 22) username = connection_info["username"] pkey = connection_info.get("pkey") password = connection_info.get("password") LOG.info( "Waiting for SSH connectivity on OSMorphing host: %(ip)s:%(port)s", { "ip": ip, "port": port }) utils.wait_for_port_connectivity(ip, port) self._event_manager.progress_update( "Connecting through SSH to OSMorphing host on: %(ip)s:%(port)s" % ({ "ip": ip, "port": port })) ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(hostname=ip, port=port, username=username, pkey=pkey, password=password) ssh.set_log_channel("paramiko.morpher.%s.%s" % (ip, port)) self._ssh = ssh
def morph_image(connection_info, target_hypervisor, target_platform, volume_devs, nics_info, event_manager): (ip, port, username, pkey) = connection_info LOG.info("Waiting for connectivity on host: %(ip)s:%(port)s", {"ip": ip, "port": port}) utils.wait_for_port_connectivity(ip, port) event_manager.progress_update( "Connecting to host: %(ip)s:%(port)s" % {"ip": ip, "port": port}) ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(hostname=ip, port=port, username=username, pkey=pkey) os_mount_tools = osmount_factory.get_os_mount_tools(ssh, event_manager) event_manager.progress_update("Discovering and mounting OS partitions") os_root_dir, other_mounted_dirs = os_mount_tools.mount_os(volume_devs) os_morphing_tools, os_info = osmorphing_factory.get_os_morphing_tools( ssh, os_root_dir, target_hypervisor, target_platform, event_manager) event_manager.progress_update('OS being migrated: %s' % str(os_info)) os_morphing_tools.set_net_config(nics_info, dhcp=True) LOG.info("Pre packages") os_morphing_tools.pre_packages_install() (packages_add, packages_remove) = os_morphing_tools.get_packages() if packages_add: event_manager.progress_update( "Adding packages: %s" % str(packages_add)) os_morphing_tools.install_packages(packages_add) if packages_remove: event_manager.progress_update( "Removing packages: %s" % str(packages_remove)) os_morphing_tools.uninstall_packages(packages_remove) LOG.info("Post packages") os_morphing_tools.post_packages_install() event_manager.progress_update("Dismounting OS partitions") os_mount_tools.dismount_os(other_mounted_dirs + [os_root_dir])
def _connect(self, connection_info): ip = connection_info["ip"] port = connection_info.get("port", 22) username = connection_info["username"] pkey = connection_info.get("pkey") password = connection_info.get("password") LOG.info("Waiting for connectivity on host: %(ip)s:%(port)s", {"ip": ip, "port": port}) utils.wait_for_port_connectivity(ip, port) self._event_manager.progress_update( "Connecting to SSH host: %(ip)s:%(port)s" % {"ip": ip, "port": port}) ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(hostname=ip, port=port, username=username, pkey=pkey, password=password) self._ssh = ssh
def _connect(self, connection_info): host = connection_info["ip"] port = connection_info.get("port", 5986) username = connection_info["username"] password = connection_info.get("password") cert_pem = connection_info.get("cert_pem") cert_key_pem = connection_info.get("cert_key_pem") url = "https://%s:%s/wsman" % (host, port) LOG.info("Connection info: %s", str(connection_info)) LOG.info("Waiting for connectivity on host: %(host)s:%(port)s", {"host": host, "port": port}) utils.wait_for_port_connectivity(host, port) self._event_manager.progress_update( "Connecting to WinRM host: %(host)s:%(port)s" % {"host": host, "port": port} ) conn = wsman.WSManConnection() conn.connect(url=url, username=username, password=password, cert_pem=cert_pem, cert_key_pem=cert_key_pem) self._conn = conn
def from_connection_info(cls, connection_info): """ Returns a wsman.WSManConnection object for the provided conn info. """ if not isinstance(connection_info, dict): raise ValueError( "WSMan connection must be a dict. Got type '%s', value: %s" % (type(connection_info), connection_info)) required_keys = ["ip", "username", "password"] missing = [key for key in required_keys if key not in connection_info] if missing: raise ValueError( "The following keys were missing from WSMan connection info %s. " "Got: %s" % (missing, connection_info)) host = connection_info["ip"] port = connection_info.get("port", 5986) username = connection_info["username"] password = connection_info.get("password") cert_pem = connection_info.get("cert_pem") cert_key_pem = connection_info.get("cert_key_pem") url = "https://%s:%s/wsman" % (host, port) LOG.info("Connection info: %s", str(connection_info)) LOG.info("Waiting for connectivity on host: %(host)s:%(port)s", { "host": host, "port": port }) utils.wait_for_port_connectivity(host, port) conn = cls() conn.connect(url=url, username=username, password=password, cert_pem=cert_pem, cert_key_pem=cert_key_pem) return conn
def _test_connection(self): """ Attempt to connect to the IP/port pair. If direct connection fails, set up a SSH tunnel and attempt a connection through that. """ if self._use_tunnel: # It was explicitly requested to use a tunnel self._setup_tunnel_connection() else: self._event_manager.progress_update( "Testing direct connection to replicator (%s:%s)" % (self._ip, self._port)) try: utils.wait_for_port_connectivity(self._ip, self._port, max_wait=30) return except BaseException as err: LOG.debug("failed to connect to %s:%s Error: %s " "Trying tunneled connection" % (self._ip, self._port, err)) self._event_manager.progress_update( "Direct connection to replicator failed. " "Setting up tunnel.") self._setup_tunnel_connection() self._event_manager.progress_update( "Testing connection to replicator (%s:%s)" % (self.repl_host, self.repl_port)) try: utils.wait_for_port_connectivity(self.repl_host, self.repl_port, max_wait=30) except BaseException as err: self._tunnel.stop() LOG.warning("failed to connect to replicator: %s" % err) raise
def copy_disk_data(target_conn_info, volumes_info, event_handler): # TODO(gsamfira): the disk image should be an URI that can either be local # (file://) or remote (https://, ftp://, smb://, nfs:// etc). # This must happen if we are to implement multi-worker scenarios. # In such cases, it is not guaranteed that the disk sync task # will be started on the same node onto which the import # happened. It may also be conceivable, that wherever the disk # image ends up, we might be able to directly expose it using # NFS, iSCSI or any other network protocol. In which case, # we can skip downloading it locally just to sync it. event_manager = events.EventManager(event_handler) ip = target_conn_info["ip"] port = target_conn_info.get("port", 22) username = target_conn_info["username"] pkey = target_conn_info.get("pkey") password = target_conn_info.get("password") event_manager.progress_update("Waiting for connectivity on %s:%s" % (ip, port)) utils.wait_for_port_connectivity(ip, port) backup_writer = backup_writers.SSHBackupWriter(ip, port, username, pkey, password, volumes_info) disk_image_reader = qemu_reader.QEMUDiskImageReader() pool = eventlet.greenpool.GreenPool() job_data = [(vol, disk_image_reader, backup_writer, event_manager) for vol in volumes_info] for result, disk_id, error in pool.imap(_copy_wrapper, job_data): # TODO(gsamfira): There is no use in letting the other disks finish # sync-ing as we don't save the state of the disk sync anywhere (yet). # When/If we ever do add this info to the database, keep track of # failures, and allow any other paralel sync to finish if error: event_manager.progress_update("Volume \"%s\" failed to sync" % disk_id) raise result[0](result[1]).with_traceback(result[2])
def _wait_for_conn(self): LOG.debug( "waiting for coriolis-writer connectivity %s:%s" % ( self._ip, self._writer_port)) utils.wait_for_port_connectivity( self._ip, self._writer_port)
def _deploy_migration_resources(self, nova, glance, neutron, migr_image_name, migr_flavor_name, migr_network_name, migr_fip_pool_name): if not glance.images.findall(name=migr_image_name): raise exception.CoriolisException( "Glance image \"%s\" not found" % migr_image_name) image = nova.images.find(name=migr_image_name) flavor = nova.flavors.find(name=migr_flavor_name) keypair = None instance = None floating_ip = None sec_group = None port = None try: migr_keypair_name = self._get_unique_name() self._event_manager.progress_update( "Creating migration worker instance keypair") k = paramiko.RSAKey.generate(2048) public_key = "ssh-rsa %s tmp@migration" % k.get_base64() keypair = self._create_keypair(nova, migr_keypair_name, public_key) self._event_manager.progress_update( "Creating migration worker instance Neutron port") port = self._create_neutron_port(neutron, migr_network_name) userdata = MIGR_USER_DATA % (MIGR_GUEST_USERNAME, public_key) instance = nova.servers.create( name=self._get_unique_name(), image=image, flavor=flavor, key_name=migr_keypair_name, userdata=userdata, nics=[{'port-id': port['id']}]) self._event_manager.progress_update( "Adding migration worker instance floating IP") floating_ip = nova.floating_ips.create(pool=migr_fip_pool_name) self._wait_for_instance(nova, instance, 'ACTIVE') LOG.info("Floating IP: %s", floating_ip.ip) instance.add_floating_ip(floating_ip) self._event_manager.progress_update( "Adding migration worker instance security group") migr_sec_group_name = self._get_unique_name() sec_group = nova.security_groups.create( name=migr_sec_group_name, description=migr_sec_group_name) nova.security_group_rules.create( sec_group.id, ip_protocol="tcp", from_port=SSH_PORT, to_port=SSH_PORT) instance.add_security_group(sec_group.id) self._event_manager.progress_update( "Waiting for connectivity on host: %(ip)s:%(port)s" % {"ip": floating_ip.ip, "port": SSH_PORT}) utils.wait_for_port_connectivity(floating_ip.ip, SSH_PORT) return _MigrationResources(nova, neutron, keypair, instance, port, floating_ip, sec_group, k) except: if instance: nova.servers.delete(instance) if floating_ip: nova.floating_ips.delete(floating_ip) if port: neutron.delete_port(port['id']) if sec_group: nova.security_groups.delete(sec_group.id) if keypair: nova.keypairs.delete(keypair.name) raise
def _deploy_migration_resources(self, nova, glance, neutron, os_type, migr_image_name, migr_flavor_name, migr_network_name, migr_fip_pool_name): if not glance.images.findall(name=migr_image_name): raise exception.CoriolisException( "Glance image \"%s\" not found" % migr_image_name) image = nova.images.find(name=migr_image_name) flavor = nova.flavors.find(name=migr_flavor_name) keypair = None instance = None floating_ip = None sec_group = None port = None try: migr_keypair_name = self._get_unique_name() self._event_manager.progress_update( "Creating migration worker instance keypair") k = paramiko.RSAKey.generate(2048) public_key = "ssh-rsa %s tmp@migration" % k.get_base64() keypair = self._create_keypair(nova, migr_keypair_name, public_key) self._event_manager.progress_update( "Creating migration worker instance Neutron port") port = self._create_neutron_port(neutron, migr_network_name) # TODO(alexpilotti): use a single username if os_type == constants.OS_TYPE_WINDOWS: username = MIGR_GUEST_USERNAME_WINDOWS else: username = MIGR_GUEST_USERNAME userdata = MIGR_USER_DATA % (username, public_key) instance = nova.servers.create( name=self._get_unique_name(), image=image, flavor=flavor, key_name=migr_keypair_name, userdata=userdata, nics=[{'port-id': port['id']}]) self._event_manager.progress_update( "Adding migration worker instance floating IP") floating_ip = nova.floating_ips.create(pool=migr_fip_pool_name) self._wait_for_instance(nova, instance, 'ACTIVE') LOG.info("Floating IP: %s", floating_ip.ip) instance.add_floating_ip(floating_ip) self._event_manager.progress_update( "Adding migration worker instance security group") if os_type == constants.OS_TYPE_WINDOWS: guest_port = WINRM_HTTPS_PORT else: guest_port = SSH_PORT migr_sec_group_name = self._get_unique_name() sec_group = nova.security_groups.create( name=migr_sec_group_name, description=migr_sec_group_name) nova.security_group_rules.create( sec_group.id, ip_protocol="tcp", from_port=guest_port, to_port=guest_port) instance.add_security_group(sec_group.id) self._event_manager.progress_update( "Waiting for connectivity on host: %(ip)s:%(port)s" % {"ip": floating_ip.ip, "port": guest_port}) utils.wait_for_port_connectivity(floating_ip.ip, guest_port) if os_type == constants.OS_TYPE_WINDOWS: password = self._get_instance_password(instance, k) else: password = None return _MigrationResources(nova, neutron, keypair, instance, port, floating_ip, guest_port, sec_group, username, password, k) except: if instance: nova.servers.delete(instance) if floating_ip: nova.floating_ips.delete(floating_ip) if port: neutron.delete_port(port['id']) if sec_group: nova.security_groups.delete(sec_group.id) if keypair: nova.keypairs.delete(keypair.name) raise