code: def openstack_undercloud_install(self):
          
          instack_undercloud_ver, _ = self.run('repoquery --whatprovides /usr/share/instack-undercloud/puppet-stack-config/puppet-stack-config.pp')
          if instack_undercloud_ver.rstrip('\n') == 'instack-undercloud-0:2.2.0-1.el7ost.noarch':
              LOG.warn('Workaround for BZ1298189')
              self.run("sed -i \"s/.*Keystone_domain\['heat_domain'\].*/Service\['keystone'\] -> Class\['::keystone::roles::admin'\] -> Class\['::heat::keystone::domain'\]/\" /usr/share/instack-undercloud/puppet-stack-config/puppet-stack-config.pp")
  
          self.run('OS_PASSWORD=bob openstack undercloud install', user='stack')
          # NOTE(Gonéri): we also need this after the overcloud deployment
          if self.run('rpm -qa openstack-ironic-api')[0].rstrip('\n') == 'openstack-ironic-api-4.2.2-3.el7ost.noarch':
              LOG.warn('Workaround for BZ1297796')
              self.run('systemctl start openstack-ironic-api.service')
          self.add_environment_file(user='stack', filename='stackrc')
          self.run('heat stack-list', user='stack')
docs: Deploy an undercloud on the host.