class openstack_tasks::roles::compute { notice('MODULAR: roles/compute.pp') $network_scheme = hiera_hash('network_scheme', {}) $network_metadata = hiera_hash('network_metadata', {}) $nova_report_interval = hiera('nova_report_interval', '60') $nova_service_down_time = hiera('nova_service_down_time', '180') prepare_network_config($network_scheme) # Pulling hiera $compute_hash = hiera_hash('compute', {}) $public_vip = hiera('public_vip') $management_vip = hiera('management_vip') $mp_hash = hiera('mp') $debug = pick($compute_hash['debug'], hiera('debug', true)) $storage_hash = hiera_hash('storage', {}) $nova_hash = hiera_hash('nova', {}) $nova_custom_hash = hiera_hash('nova_custom', {}) $rabbit_hash = hiera_hash('rabbit', {}) $cinder_hash = hiera_hash('cinder', {}) $ceilometer_hash = hiera_hash('ceilometer', {}) $access_hash = hiera_hash('access', {}) $syslog_hash = hiera_hash('syslog', {}) $base_syslog_hash = hiera_hash('base_syslog', {}) $use_syslog = hiera('use_syslog', true) $use_stderr = hiera('use_stderr', false) $syslog_log_facility = hiera('syslog_log_facility_nova','LOG_LOCAL6') $config_drive_format = pick($compute_hash['config_drive_format'], 'vfat') $public_ssl_hash = hiera_hash('public_ssl') $ssl_hash = hiera_hash('use_ssl', {}) $node_hash = hiera_hash('node', {}) $use_huge_pages = pick($node_hash['nova_hugepages_enabled'], false) $allocated_hugepages = parsejson($::allocated_hugepages) $use_2m_huge_pages = $allocated_hugepages['2M'] $use_1g_huge_pages = $allocated_hugepages['1G'] $libvirt_type = hiera('libvirt_type', undef) $kombu_compression = hiera('kombu_compression', $::os_service_default) $nova_cache = pick($nova_hash['use_cache'], true) $region_name = hiera('region', 'RegionOne') # get glance api servers list $glance_endpoint_default = hiera('glance_endpoint', $management_vip) $glance_protocol = get_ssl_property($ssl_hash, {}, 'glance', 'internal', 'protocol', 'http') $glance_endpoint = get_ssl_property($ssl_hash, {}, 'glance', 'internal', 'hostname', $glance_endpoint_default) $glance_api_servers = hiera('glance_api_servers', "${glance_protocol}://${glance_endpoint}:9292") $vncproxy_protocol = get_ssl_property($ssl_hash, $public_ssl_hash, 'nova', 'public', 'protocol', [$nova_hash['vncproxy_protocol'], 'http']) $vncproxy_host = get_ssl_property($ssl_hash, $public_ssl_hash, 'nova', 'public', 'hostname', [$public_vip]) $block_device_allocate_retries = hiera('block_device_allocate_retries', 300) $block_device_allocate_retries_interval = hiera('block_device_allocate_retries_interval', 3) $transport_url = hiera('transport_url','rabbit://guest:password@127.0.0.1:5672/') include ::osnailyfacter::test_compute $floating_hash = {} ##CALCULATED PARAMETERS $memcached_servers = hiera('memcached_servers') $local_memcached_server = hiera('local_memcached_server') # TODO(xarses): We need to validate this is needed if ($storage_hash['volumes_lvm']) { nova_config { 'keymgr/fixed_key': value => $cinder_hash[fixed_key]; } } # Use Swift if it isn't replaced by Ceph for BOTH images and objects if !($storage_hash['images_ceph'] and $storage_hash['objects_ceph']) { $use_swift = true } else { $use_swift = false } # Get reserved host memory straight value if we've ceph neighbor $r_hostmem = roles_include(['ceph-osd']) ? { true => min(max(floor($::memorysize_mb*0.2), 512), 1536), false => undef, } $mirror_type = 'external' Exec { logoutput => true } $nova_hash_real = merge({ 'reserved_host_memory' => $r_hostmem }, $nova_hash) # Required for fping API extension, see LP#1486404 ensure_packages('fping') $nova_config_hash = { 'DEFAULT/use_cow_images' => { value => hiera('use_cow_images', 'True') }, 'libvirt/libvirt_inject_key' => { value => true }, 'libvirt/libvirt_inject_password' => { value => true }, } $nova_complete_hash = merge($nova_config_hash, $nova_custom_hash) class { '::nova::config': nova_config => $nova_complete_hash, } $rabbit_heartbeat_timeout_threshold = pick($nova_hash['rabbit_heartbeat_timeout_threshold'], $rabbit_hash['heartbeat_timeout_threshold'], 60) $rabbit_heartbeat_rate = pick($nova_hash['rabbit_heartbeat_rate'], $rabbit_hash['rabbit_heartbeat_rate'], 2) ######################################################################## include ::nova::params case $::osfamily { 'RedHat': { # From legacy libvirt.pp exec { 'symlink-qemu-kvm': command => '/bin/ln -sf /usr/libexec/qemu-kvm /usr/bin/qemu-system-x86_64', creates => '/usr/bin/qemu-system-x86_64', } package { 'avahi': ensure => present; } service { 'avahi-daemon': ensure => running, require => Package['avahi']; } Package['avahi'] -> Service['messagebus'] -> Service['avahi-daemon'] -> Service['libvirt'] service { 'libvirt-guests': ensure => true, name => 'libvirt-guests', enable => false, hasstatus => false, hasrestart => false, } # From legacy params.pp $libvirt_type_kvm = 'qemu-kvm' $guestmount_package_name = 'libguestfs-tools-c' # From legacy utilities.pp package { ['unzip', 'curl', 'euca2ools']: ensure => present } if !(defined(Package['parted'])) { package {'parted': ensure => 'present' } } package {$guestmount_package_name: ensure => present} } 'Debian': { # From legacy params $libvirt_type_kvm = 'qemu-kvm' $guestmount_package_name = 'guestmount' } default: { fail("Unsupported osfamily: ${::osfamily}") } } if $::osfamily == 'Debian' { if $use_huge_pages { if $use_1g_huge_pages { $hugepages_1g_opts_ensure = 'present' file { '/mnt/hugepages_1GB': ensure => 'directory', owner => 'root', group => 'kvm', mode => '0775', require => Package[$libvirt_type_kvm], } exec { 'mount_hugetlbfs_1g': command => 'mount -t hugetlbfs hugetlbfs-kvm -o mode=775,gid=kvm,pagesize=1GB /mnt/hugepages_1GB', unless => 'grep -q /mnt/hugepages_1GB /proc/mounts', path => '/usr/sbin:/usr/bin:/sbin:/bin', require => File['/mnt/hugepages_1GB'], } if $use_2m_huge_pages { $libvirt_hugetlbfs_mount = 'hugetlbfs_mount = ["/run/hugepages/kvm", "/mnt/hugepages_1GB"]' $qemu_hugepages_value = 'set KVM_HUGEPAGES 1' } else { $libvirt_hugetlbfs_mount = 'hugetlbfs_mount = "/mnt/hugepages_1GB"' $qemu_hugepages_value = 'rm KVM_HUGEPAGES' } } else { $qemu_hugepages_value = 'set KVM_HUGEPAGES 1' $libvirt_hugetlbfs_mount = 'hugetlbfs_mount = "/run/hugepages/kvm"' } } else { $qemu_hugepages_value = 'rm KVM_HUGEPAGES' $libvirt_hugetlbfs_mount = 'hugetlbfs_mount = ""' } # At this point $hugepages_1g_opts_ensure can be set to 'absent' or unset # Make sure that it's set to 'absent' and avoid errors if ! $hugepages_1g_opts_ensure { $hugepages_1g_opts_ensure = 'absent' } augeas { 'qemu_hugepages': context => '/files/etc/default/qemu-kvm', changes => $qemu_hugepages_value, notify => Service['libvirt'], } file_line { 'libvirt_hugetlbfs_mount': path => '/etc/libvirt/qemu.conf', line => $libvirt_hugetlbfs_mount, match => '^hugetlbfs_mount =.*$', require => Package['libvirt'], notify => Service['libvirt'], } file_line { 'libvirt_1g_hugepages_apparmor': ensure => $hugepages_1g_opts_ensure, path => '/etc/apparmor.d/abstractions/libvirt-qemu', after => 'owner "/run/hugepages/kvm/libvirt/qemu/', line => ' owner "/mnt/hugepages_1GB/libvirt/qemu/**" rw,', require => Package['libvirt'], notify => Exec['refresh_apparmor'], } file_line { '1g_hugepages_fstab': ensure => $hugepages_1g_opts_ensure, path => '/etc/fstab', line => 'hugetlbfs-kvm /mnt/hugepages_1GB hugetlbfs mode=775,gid=kvm,pagesize=1GB 0 0', } Augeas['qemu_hugepages'] ~> Service<| title == 'qemu-kvm'|> Service<| title == 'qemu-kvm'|> -> Service<| title == 'libvirt'|> } if ($::operatingsystem == 'Ubuntu') and ($libvirt_type =='kvm') { # TODO(skolekonov): Remove when LP#1057024 has been resolved. # https://bugs.launchpad.net/ubuntu/+source/qemu-kvm/+bug/1057024 file { '/dev/kvm': ensure => present, group => 'kvm', mode => '0660', } Service<| title == 'qemu-kvm'|> -> File['/dev/kvm'] } $notify_on_state_change = 'vm_and_task_state' class { '::nova': default_transport_url => $transport_url, glance_api_servers => $glance_api_servers, debug => $debug, use_syslog => $use_syslog, use_stderr => $use_stderr, log_facility => $syslog_log_facility, state_path => $nova_hash_real['state_path'], report_interval => $nova_report_interval, service_down_time => $nova_service_down_time, notify_on_state_change => $notify_on_state_change, notification_driver => $ceilometer_hash['notification_driver'], cinder_catalog_info => pick($nova_hash_real['cinder_catalog_info'], 'volumev2:cinderv2:internalURL'), kombu_compression => $kombu_compression, block_device_allocate_retries => $block_device_allocate_retries, block_device_allocate_retries_interval => $block_device_allocate_retries_interval, rabbit_heartbeat_timeout_threshold => $rabbit_heartbeat_timeout_threshold, rabbit_heartbeat_rate => $rabbit_heartbeat_rate, os_region_name => $region_name, } class { '::nova::cache': enabled => $nova_cache, backend => 'oslo_cache.memcache_pool', memcache_servers => $local_memcached_server, } class { '::nova::availability_zone': default_availability_zone => $nova_hash_real['default_availability_zone'], default_schedule_zone => $nova_hash_real['default_schedule_zone'], } # CPU configuration created using host-model may not work as expected. # The guest CPU may differ from the configuration and it may also confuse # guest OS by using a combination of CPU features and other parameters (such # as CPUID level) that don't work. Until these issues are fixed, it's a good # idea to avoid using host-model # http://libvirt.org/formatdomain.html#elementsCPU # https://bugs.launchpad.net/mos/+bug/1618473 $libvirt_cpu_mode = 'none' # Install / configure nova-compute # From legacy ceilometer notifications for nova $instance_usage_audit = true $instance_usage_audit_period = 'hour' ####### Disable upstart startup on install ####### if($::operatingsystem == 'Ubuntu') { tweaks::ubuntu_service_override { 'nova-compute': package_name => "nova-compute-${libvirt_type}", } } # Explicitly disable file injection by the means of nbd and libguestfs: # the former is known to have reliability problems, while the latter does not # work out of box on Ubuntu. Neither works with Ceph ephemerals. The solution # here is to use config drive + cloud-init instead. This allows us to unify # settings for Ubuntu vs CentOS, as well as Ceph vs file ephemerals. # See LP #1467860 , LP #1556819 and LP #1467579 for details. $libvirt_inject_partition = '-2' $force_config_drive = true # NOTE(bogdando) deploy compute node with disabled nova-compute # service #LP1398817. The orchestration will start and enable it back # after the deployment is done. # NOTE(bogdando) This maybe be changed, if the host aggregates implemented, bp disable-new-computes class { '::nova::compute': enabled => false, vncserver_proxyclient_address => get_network_role_property('nova/api', 'ipaddr'), vncproxy_protocol => $vncproxy_protocol, vncproxy_host => $vncproxy_host, vncproxy_port => $nova_hash_real['vncproxy_port'], force_config_drive => $force_config_drive, pci_passthrough => nic_whitelist_to_json(get_nic_passthrough_whitelist('sriov')), instance_usage_audit => $instance_usage_audit, instance_usage_audit_period => $instance_usage_audit_period, reserved_host_memory => $nova_hash_real['reserved_host_memory'], config_drive_format => $config_drive_format, allow_resize_to_same_host => true, vcpu_pin_set => $nova_hash_real['cpu_pinning'], resume_guests_state_on_host_boot => hiera('resume_guests_state_on_host_boot', 'False'), } nova_config { 'libvirt/live_migration_flag': value => 'VIR_MIGRATE_UNDEFINE_SOURCE,VIR_MIGRATE_PEER2PEER,VIR_MIGRATE_LIVE,VIR_MIGRATE_PERSIST_DEST'; 'libvirt/block_migration_flag': value => 'VIR_MIGRATE_UNDEFINE_SOURCE,VIR_MIGRATE_PEER2PEER,VIR_MIGRATE_LIVE,VIR_MIGRATE_NON_SHARED_INC'; 'DEFAULT/connection_type': value => 'libvirt'; } # TODO (iberezovskiy): rework this option management once it's available in puppet-nova module if !defined(Nova_config['privsep_osbrick/helper_command']) { nova_config { 'privsep_osbrick/helper_command': value => 'sudo nova-rootwrap /etc/nova/rootwrap.conf privsep-helper --config-file /etc/nova/nova.conf' } } if $use_syslog { nova_config { 'DEFAULT/use_syslog_rfc_format': value => true; } } if ($storage_hash['ephemeral_ceph'] or $storage_hash['volumes_ceph']) { $disk_cachemodes = ['"network=writeback,block=none"'] } else { $disk_cachemodes = ['"file=directsync,block=none"'] } # set image preallocation mode $preallocate_images = pick($nova_hash_real['preallocate_images'], 'space') validate_re($preallocate_images, '^(none|space)$') # Configure libvirt for nova-compute class { '::nova::compute::libvirt': libvirt_virt_type => $libvirt_type, libvirt_cpu_mode => $libvirt_cpu_mode, libvirt_disk_cachemodes => $disk_cachemodes, libvirt_inject_partition => $libvirt_inject_partition, vncserver_listen => '0.0.0.0', remove_unused_original_minimum_age_seconds => pick($nova_hash_real['remove_unused_original_minimum_age_seconds'], '86400'), libvirt_service_name => 'libvirt-bin', virtlock_service_name => 'virtlockd', virtlog_service_name => 'virtlogd', preallocate_images => $preallocate_images, } class { '::nova::migration::libvirt': override_uuid => true, } # From legacy libvirt.pp if $::operatingsystem == 'Ubuntu' { package { 'cpufrequtils': ensure => present; } file { '/etc/default/cpufrequtils': content => "GOVERNOR=\"performance\"\n", require => Package['cpufrequtils'], notify => Service['cpufrequtils'], } service { 'cpufrequtils': ensure => 'running', enable => true, status => '/bin/true', } Package<| title == 'cpufrequtils'|> ~> Service<| title == 'cpufrequtils'|> if !defined(Service['cpufrequtils']) { notify{ "Module ${module_name} cannot notify service cpufrequtils on package update": } } } package { $libvirt_type_kvm: ensure => present, before => Package[$::nova::params::compute_package_name], } case $::osfamily { 'RedHat': { if $libvirt_type =='kvm' { exec { '/etc/sysconfig/modules/kvm.modules': path => '/sbin:/usr/sbin:/bin:/usr/bin', unless => 'lsmod | grep -q kvm', require => Package[$libvirt_type_kvm], } } } 'Debian': { service { 'qemu-kvm': ensure => running, require => Package[$libvirt_type_kvm], subscribe => Package[$libvirt_type_kvm], } } default: { fail("Unsupported osfamily: ${::osfamily}") } } Service<| title == 'libvirt'|> ~> Service<| title == 'nova-compute'|> Package<| title == "nova-compute-${libvirt_type}"|> ~> Service<| title == 'nova-compute'|> case $::osfamily { 'RedHat': { if str2bool("${::selinux}") { file_line { 'qemu_selinux': path => '/etc/libvirt/qemu.conf', line => 'security_driver = "selinux"', require => Package['libvirt'], notify => Service['libvirt'] } } else { file_line { 'qemu_selinux_disabled': ensure => absent, path => '/etc/libvirt/qemu.conf', match => '^security_driver', match_for_absence => true, require => Package['libvirt'], notify => Service['libvirt'] } } } 'Debian': { package { 'apparmor': ensure => installed, } service { 'apparmor': ensure => running, require => Package['apparmor'], } file_line { 'qemu_apparmor': path => '/etc/libvirt/qemu.conf', line => 'security_driver = "apparmor"', require => [Package['libvirt'], Service['apparmor']], notify => Service['libvirt'] } file_line { 'apparmor_libvirtd': path => '/etc/apparmor.d/usr.sbin.libvirtd', line => "# unix, # shouldn't be used for libvirt/qemu", match => '^[#[:space:]]*unix', require => Package['libvirt'], } exec { 'refresh_apparmor': refreshonly => true, command => '/sbin/apparmor_parser -r /etc/apparmor.d/usr.sbin.libvirtd', require => Package['apparmor'], subscribe => File_line['apparmor_libvirtd'], } } default: { fail("Unsupported osfamily: ${::osfamily}") } } Package<| title == 'nova-compute'|> ~> Service<| title == 'nova-compute'|> if !defined(Service['nova-compute']) { notify{ "Module ${module_name} cannot notify service nova-compute on packages update": } } Package<| title == 'libvirt'|> ~> Service<| title == 'libvirt'|> if !defined(Service['libvirt']) { notify{ "Module ${module_name} cannot notify service libvirt on package update": } } include ::nova::client # Ensure ssh clients are installed case $::osfamily { 'Debian': { $scp_package='openssh-client' $multipath_tools_package='multipath-tools' } 'RedHat': { $scp_package='openssh-clients' $multipath_tools_package='device-mapper-multipath' } default: { fail("Unsupported osfamily: ${::osfamily}") } } ensure_packages([$scp_package, $multipath_tools_package]) # Configure ssh key authentication between compute nodes # (required for non-live/cold migration) $ssh_key_path = '/var/lib/astute/nova' install_ssh_keys { 'nova_ssh_key_for_migration': ensure => present, user => 'nova', private_key_path => "${ssh_key_path}/nova", public_key_path => "${ssh_key_path}/nova.pub", } -> file { '/var/lib/nova/.ssh/config': ensure => present, owner => 'nova', group => 'nova', mode => '0600', content => "Host *\n StrictHostKeyChecking no\n", } user { 'nova': ensure => present, shell => '/bin/rbash', require => Package['nova-common'], } }