Add hooks for external install & svc management

This adds defined anchor points for external modules to hook into the
software install, config and service dependency chain.  This allows
external modules to manage software installation (virtualenv,
containers, etc) and service management (pacemaker) without needing rely
on resources that may change or be renamed.

Change-Id: I31c023824e428ad0fc3dad30b4d3103aaa747597
This commit is contained in:
Adam Vinsh 2016-09-13 16:17:10 +00:00
parent d7724c729a
commit 9fe25f3a23
34 changed files with 174 additions and 55 deletions

View File

@ -113,6 +113,7 @@ class ironic::api (
$memcached_servers = undef,
) inherits ironic::params {
include ::ironic::deps
include ::ironic::params
include ::ironic::policy
@ -142,9 +143,6 @@ class ironic::api (
include ::ironic::api::authtoken
Ironic_config<||> ~> Service[$service_name]
Class['ironic::policy'] ~> Service[$service_name]
# Configure ironic.conf
ironic_config {
'api/host_ip': value => $host_ip;
@ -157,8 +155,6 @@ class ironic::api (
# Install package
if $::ironic::params::api_package {
Package['ironic-api'] -> Class['ironic::policy']
Package['ironic-api'] -> Service[$service_name]
package { 'ironic-api':
ensure => $package_ensure,
name => $::ironic::params::api_package,

View File

@ -228,6 +228,8 @@ class ironic::api::authtoken(
$token_cache_time = $::os_service_default,
) {
include ::ironic::deps
if is_service_default($password) and ! $::ironic::api::admin_password {
fail('Please set password for Ironic API service user')
}

View File

@ -190,6 +190,8 @@ class ironic::bifrost (
$ipmi_bridging = 'no',
) {
include ::ironic::deps
vcsrepo { $git_dest_repo_folder:
ensure => $ensure,
provider => git,

View File

@ -30,12 +30,13 @@ class ironic::client (
$package_ensure = present
) {
include ::ironic::deps
include ::ironic::params
package { 'python-ironicclient':
ensure => $package_ensure,
name => $::ironic::params::client_package,
tag => 'openstack',
tag => ['openstack', 'ironic-support-package'],
}
}

View File

@ -127,11 +127,10 @@ class ironic::conductor (
$configdrive_swift_container = $::os_service_default,
) {
include ::ironic::deps
include ::ironic::params
include ::ironic::drivers::deploy
Ironic_config<||> ~> Service['ironic-conductor']
$enabled_drivers_real = pick($::ironic::enabled_drivers, $enabled_drivers)
validate_array($enabled_drivers_real)
@ -200,7 +199,6 @@ class ironic::conductor (
# Install package
if $::ironic::params::conductor_package {
Package<| tag == 'ironic-package' |> -> Service['ironic-conductor']
package { 'ironic-conductor':
ensure => $package_ensure,
name => $::ironic::params::conductor_package,

View File

@ -28,6 +28,7 @@ class ironic::config (
$ironic_api_paste_ini = {},
) {
include ::ironic::deps
validate_hash($ironic_config)
validate_hash($ironic_api_paste_ini)

View File

@ -45,6 +45,8 @@ class ironic::cors (
$allow_headers = $::os_service_default,
) {
include ::ironic::deps
oslo::cors { 'ironic_config':
allowed_origin => $allowed_origin,
allow_credentials => $allow_credentials,

View File

@ -48,6 +48,7 @@ class ironic::db (
$database_max_overflow = $::os_service_default,
$database_db_max_retries = $::os_service_default,
) {
include ::ironic::deps
# NOTE(spredzy): In order to keep backward compatibility we rely on the pick function
# to use ironic::<myparam> if ironic::db::<myparam> isn't specified.

View File

@ -3,19 +3,20 @@
#
class ironic::db::inspector_sync {
include ::ironic::deps
include ::ironic::params
Package<| tag == 'ironic-inspector-package' |> ~> Exec['ironic-inspector-dbsync']
Exec['ironic-inspector-dbsync'] ~> Service <| tag == 'ironic-inspector-service' |>
Ironic_inspector_config<||> -> Exec['ironic-inspector-dbsync']
Ironic_inspector_config<| title == 'database/connection' |> ~> Exec['ironic-inspector-dbsync']
exec { 'ironic-inspector-dbsync':
command => $::ironic::params::inspector_dbsync_command,
path => '/usr/bin',
user => 'ironic-inspector',
refreshonly => true,
logoutput => on_failure,
subscribe => [
Anchor['ironic-inspector::install::end'],
Anchor['ironic-inspector::config::end'],
Anchor['ironic-inspector::dbsync::begin']
],
notify => Anchor['ironic-inspector::dbsync::end'],
}
}

View File

@ -54,6 +54,8 @@ class ironic::db::mysql (
$collate = 'utf8_general_ci',
) {
include ::ironic::deps
::openstacklib::db::mysql { 'ironic':
user => $user,
password_hash => mysql_password($password),
@ -64,6 +66,7 @@ class ironic::db::mysql (
allowed_hosts => $allowed_hosts,
}
::Openstacklib::Db::Mysql['ironic'] ~> Exec<| title == 'ironic-dbsync' |>
Anchor['ironic::db::begin']
~> Class['ironic::db::mysql']
~> Anchor['ironic::db::end']
}

View File

@ -32,7 +32,7 @@ class ironic::db::postgresql(
$privileges = 'ALL',
) {
Class['ironic::db::postgresql'] -> Service<| title == 'ironic' |>
include ::ironic::deps
::openstacklib::db::postgresql { 'ironic':
password_hash => postgresql_password($user, $password),
@ -42,6 +42,7 @@ class ironic::db::postgresql(
privileges => $privileges,
}
::Openstacklib::Db::Postgresql['ironic'] ~> Exec<| title == 'ironic-dbsync' |>
Anchor['ironic::db::begin']
~> Class['ironic::db::postgresql']
~> Anchor['ironic::db::end']
}

View File

@ -12,14 +12,9 @@ class ironic::db::sync(
$extra_params = undef,
) {
include ::ironic::deps
include ::ironic::params
Package<| tag == 'ironic-package' |> ~> Exec['ironic-dbsync']
Exec['ironic-dbsync'] ~> Service <| tag == 'ironic-service' |>
Ironic_config<||> -> Exec['ironic-dbsync']
Ironic_config<| title == 'database/connection' |> ~> Exec['ironic-dbsync']
exec { 'ironic-dbsync':
command => "${::ironic::params::dbsync_command} ${extra_params}",
path => '/usr/bin',
@ -31,5 +26,11 @@ class ironic::db::sync(
user => 'root',
refreshonly => true,
logoutput => on_failure,
subscribe => [
Anchor['ironic::install::end'],
Anchor['ironic::config::end'],
Anchor['ironic::dbsync::begin']
],
notify => Anchor['ironic::dbsync::end'],
}
}

72
manifests/deps.pp Normal file
View File

@ -0,0 +1,72 @@
# == Class: ironic::deps
#
# ironic anchors and dependency management
#
class ironic::deps {
# Setup anchors for install, config and service phases of the module. These
# anchors allow external modules to hook the begin and end of any of these
# phases. Package or service management can also be replaced by ensuring the
# package is absent or turning off service management and having the
# replacement depend on the appropriate anchors. When applicable, end tags
# should be notified so that subscribers can determine if installation,
# config or service state changed and act on that if needed.
anchor { 'ironic::install::begin': }
-> Package<| tag == 'ironic-package'|>
~> anchor { 'ironic::install::end': }
-> anchor { 'ironic::config::begin': }
-> Ironic_config<||>
~> anchor { 'ironic::config::end': }
-> anchor { 'ironic::db::begin': }
-> anchor { 'ironic::db::end': }
~> anchor { 'ironic::dbsync::begin': }
-> anchor { 'ironic::dbsync::end': }
~> anchor { 'ironic::service::begin': }
~> Service<| tag == 'ironic-service' |>
~> anchor { 'ironic::service::end': }
# paste-api.ini config should occur in the config block also.
Anchor['ironic::config::begin']
-> Ironic_api_paste_ini<||>
~> Anchor['ironic::config::end']
# ironic-inspector is supported by this module. This service uses a
# specific conf file and uses it's own config provider. Split out install
# and configure of this service so that other services are not affected.
anchor { 'ironic-inspector::install::begin': }
-> Package<| tag == 'ironic-inspector-package'|>
~> anchor { 'ironic-inspector::install::end': }
-> anchor { 'ironic-inspector::config::begin': }
-> Ironic_inspector_config<||>
~> anchor { 'ironic-inspector::config::end': }
-> anchor { 'ironic-inspector::dbsync::begin': }
-> anchor { 'ironic-inspector::dbsync::end': }
~> anchor { 'ironic-inspector::service::begin': }
~> Service<| tag == 'ironic-inspector-service' |>
~> Service<| tag == 'ironic-inspector-dnsmasq-service' |>
~> anchor { 'ironic-inspector::service::end': }
Anchor['ironic::db::end']
-> Anchor['ironic-inspector::dbsync::begin']
# Support packages need to be installed in the install phase, but we don't
# put them in the chain above because we don't want any false dependencies
# between packages with the ironic-package tag and the ironic-support-package
# tag. Note: the package resources here will have a 'before' relationshop on
# the ironic::install::end anchor. The line between ironic-support-package and
# ironic-package should be whether or not ironic services would need to be
# restarted if the package state was changed.
Anchor['ironic::install::begin']
-> Package<| tag == 'ironic-support-package'|>
-> Anchor['ironic::install::end']
# ironic-inspector depends on support packages in pxe.pp
Anchor['ironic-inspector::install::begin']
-> Package<| tag == 'ironic-support-package'|>
-> Anchor['ironic-inspector::install::end']
# Installation or config changes will always restart services.
Anchor['ironic::install::end'] ~> Anchor['ironic::service::begin']
Anchor['ironic::config::end'] ~> Anchor['ironic::service::begin']
Anchor['ironic-inspector::install::end'] ~> Anchor['ironic-inspector::service::begin']
Anchor['ironic-inspector::config::end'] ~> Anchor['ironic-inspector::service::begin']
}

View File

@ -65,6 +65,8 @@ class ironic::drivers::agent (
$deploy_logs_swift_days_to_expire = $::os_service_default,
) {
include ::ironic::deps
# Configure ironic.conf
ironic_config {
'agent/stream_raw_images': value => $stream_raw_images;

View File

@ -29,6 +29,8 @@ class ironic::drivers::ipmi (
$retry_timeout = '10'
) {
include ::ironic::deps
# Configure ironic.conf
ironic_config {
'ipmi/retry_timeout': value => $retry_timeout;

View File

@ -113,6 +113,7 @@ class ironic::drivers::pxe (
$pxe_deploy_timeout = undef,
) {
include ::ironic::deps
include ::ironic::pxe::common
$tftp_root_real = pick($::ironic::pxe::common::tftp_root, $tftp_root)
$ipxe_timeout_real = pick($::ironic::pxe::common::ipxe_timeout, $ipxe_timeout)

View File

@ -26,6 +26,8 @@ class ironic::drivers::ssh (
$libvirt_uri = $::os_service_default,
) {
include ::ironic::deps
# Configure ironic.conf
ironic_config {
'ssh/libvirt_uri': value => $libvirt_uri;

View File

@ -360,6 +360,7 @@ class ironic (
$enabled_drivers = undef,
) {
include ::ironic::deps
include ::ironic::logging
include ::ironic::db
include ::ironic::params
@ -380,14 +381,12 @@ class ironic (
name => $::ironic::params::common_package_name,
tag => ['openstack', 'ironic-package'],
}
Package['ironic-common'] ~> Service<| tag == 'ironic-service' |>
package { 'ironic-lib':
ensure => $package_ensure,
name => $::ironic::params::lib_package_name,
tag => ['openstack', 'ironic-package'],
}
Package['ironic-lib'] ~> Service<| tag == 'ironic-service' |>
resources { 'ironic_config':
purge => $purge_config,

View File

@ -225,6 +225,7 @@ class ironic::inspector (
$auth_uri = undef,
) {
include ::ironic::deps
include ::ironic::params
include ::ironic::pxe::common
include ::ironic::inspector::logging
@ -261,18 +262,16 @@ class ironic::inspector (
$http_port_real = pick($::ironic::pxe::common::http_port, $http_port)
$ipxe_timeout_real = pick($::ironic::pxe::common::ipxe_timeout, $ipxe_timeout)
Ironic_inspector_config<||> ~> Service['ironic-inspector']
file { '/etc/ironic-inspector/inspector.conf':
ensure => 'present',
require => Package['ironic-inspector'],
require => Anchor['ironic-inspector::config::begin'],
}
if $pxe_transfer_protocol == 'tftp' {
file { '/etc/ironic-inspector/dnsmasq.conf':
ensure => 'present',
content => template('ironic/inspector_dnsmasq_tftp.erb'),
require => Package['ironic-inspector'],
require => Anchor['ironic-inspector::config::begin'],
}
file { "${tftp_root_real}/pxelinux.cfg/default":
ensure => 'present',
@ -280,7 +279,7 @@ class ironic::inspector (
owner => 'ironic-inspector',
group => 'ironic-inspector',
content => template('ironic/inspector_pxelinux_cfg.erb'),
require => Package['ironic-inspector'],
require => Anchor['ironic-inspector::config::begin'],
}
}
@ -288,7 +287,7 @@ class ironic::inspector (
file { '/etc/ironic-inspector/dnsmasq.conf':
ensure => 'present',
content => template('ironic/inspector_dnsmasq_http.erb'),
require => Package['ironic-inspector'],
require => Anchor['ironic-inspector::config::begin'],
}
file { "${http_root_real}/inspector.ipxe":
ensure => 'present',
@ -296,7 +295,7 @@ class ironic::inspector (
owner => 'ironic-inspector',
group => 'ironic-inspector',
content => template('ironic/inspector_ipxe.erb'),
require => Package['ironic-inspector'],
require => Anchor['ironic-inspector::config::begin'],
}
}
@ -330,8 +329,6 @@ class ironic::inspector (
# Install package
if $::ironic::params::inspector_package {
Package['ironic-inspector'] -> Service['ironic-inspector']
Package['ironic-inspector'] -> Service['ironic-inspector-dnsmasq']
package { 'ironic-inspector':
ensure => $package_ensure,
name => $::ironic::params::inspector_package,
@ -358,7 +355,6 @@ class ironic::inspector (
tag => 'ironic-inspector-service',
}
Service['ironic-inspector'] -> Service['ironic-inspector-dnsmasq']
service { 'ironic-inspector-dnsmasq':
ensure => $ensure,
name => $::ironic::params::inspector_dnsmasq_service,

View File

@ -228,6 +228,8 @@ class ironic::inspector::authtoken(
$token_cache_time = $::os_service_default,
) {
include ::ironic::deps
if is_service_default($password) and ! $::ironic::inspector::admin_password {
fail('Please set password for Ironic Inspector service user')
}

View File

@ -112,6 +112,8 @@ class ironic::inspector::logging(
$verbose = undef,
) {
include ::ironic::deps
$debug_real = pick($::ironic::inspector::debug,$debug)
if is_service_default($default_log_levels) {
$default_log_levels_real = $default_log_levels

View File

@ -95,6 +95,8 @@ class ironic::keystone::auth (
$internal_url = 'http://127.0.0.1:6385',
) {
include ::ironic::deps
if $configure_user_role {
Keystone_user_role["${auth_name}@${tenant}"] ~> Service <| name == 'ironic-server' |>
}

View File

@ -95,6 +95,8 @@ class ironic::keystone::auth_inspector (
$internal_url = 'http://127.0.0.1:5050',
) {
include ::ironic::deps
$real_service_name = pick($service_name, $auth_name)
if $configure_user_role {

View File

@ -116,6 +116,8 @@ class ironic::logging(
$verbose = undef,
) {
include ::ironic::deps
# NOTE(spredzy): In order to keep backward compatibility we rely on the pick function
# to use ironic::<myparam> first then ironic::logging::<myparam>.
$use_syslog_real = pick($::ironic::use_syslog,$use_syslog)

View File

@ -18,6 +18,8 @@ class ironic::policy (
$policy_path = '/etc/ironic/policy.json',
) {
include ::ironic::deps
validate_hash($policies)
Openstacklib::Policy::Base {

View File

@ -51,6 +51,7 @@ class ironic::pxe (
$syslinux_files = $::ironic::params::syslinux_files,
) inherits ::ironic::params {
include ::ironic::deps
include ::ironic::pxe::common
$tftp_root_real = pick($::ironic::pxe::common::tftp_root, $tftp_root)
@ -62,7 +63,8 @@ class ironic::pxe (
seltype => 'tftpdir_t',
owner => 'ironic',
group => 'ironic',
require => Package['ironic-common'],
require => Anchor['ironic::config::begin'],
before => Anchor['ironic::config::end'],
}
file { "${tftp_root_real}/pxelinux.cfg":
@ -78,13 +80,14 @@ class ironic::pxe (
seltype => 'httpd_sys_content_t',
owner => 'ironic',
group => 'ironic',
require => Package['ironic-common'],
require => Anchor['ironic::config::begin'],
before => Anchor['ironic::config::end'],
}
ensure_resource( 'package', 'tftp-server', {
'ensure' => $package_ensure,
'name' => $::ironic::params::tftpd_package,
'tag' => ['openstack', 'ironic-ipxe'],
'tag' => ['openstack', 'ironic-ipxe', 'ironic-support-package'],
})
$options = "--map-file ${tftp_root_real}/map-file"
@ -100,7 +103,7 @@ class ironic::pxe (
flags => 'IPv4',
per_source => '11',
wait => 'yes',
require => Package['tftp-server'],
subscribe => Anchor['ironic::install::end'],
}
file { "${tftp_root_real}/map-file":
@ -123,7 +126,7 @@ class ironic::pxe (
ensure_resource( 'package', 'ipxe', {
ensure => $package_ensure,
name => $::ironic::params::ipxe_package,
tag => ['openstack', 'ironic-ipxe'],
tag => ['openstack', 'ironic-ipxe', 'ironic-support-package'],
})
file { "${tftp_root_real}/undionly.kpxe":

View File

@ -43,4 +43,5 @@ class ironic::pxe::common (
$http_port = undef,
$ipxe_timeout = undef,
) {
include ::ironic::deps
}

View File

@ -32,6 +32,8 @@ define ironic::pxe::tftpboot_file (
$destination_directory,
$file = $title,
) {
include ::ironic::deps
file {"${destination_directory}/${file}":
ensure => 'present',
seltype => 'tftpdir_t',

View File

@ -91,6 +91,7 @@ class ironic::wsgi::apache (
$priority = '10',
) {
include ::ironic::deps
include ::ironic::params
include ::apache
include ::apache::mod::wsgi

View File

@ -0,0 +1,8 @@
---
features:
- Add hooks for external install & svc management
This adds defined anchor points for external modules to hook into the
software install, config and service dependency chain. This allows
external modules to manage software installation (virtualenv,
containers, etc) and service management (pacemaker) without needing rely
on resources that may change or be renamed.

View File

@ -51,7 +51,8 @@ describe 'ironic::api' do
:ensure => p[:package_ensure],
:tag => ['openstack', 'ironic-package'],
)
is_expected.to contain_package('ironic-api').with_before(/Service\[ironic-api\]/)
is_expected.to contain_package('ironic-api').that_requires('Anchor[ironic::install::begin]')
is_expected.to contain_package('ironic-api').that_notifies('Anchor[ironic::install::end]')
end
end

View File

@ -49,7 +49,8 @@ describe 'ironic::conductor' do
:ensure => p[:package_ensure],
:tag => ['openstack', 'ironic-package'],
)
is_expected.to contain_package('ironic-conductor').with_before(/Service\[ironic-conductor\]/)
is_expected.to contain_package('ironic-conductor').that_requires('Anchor[ironic::install::begin]')
is_expected.to contain_package('ironic-conductor').that_notifies('Anchor[ironic::install::end]')
end
end

View File

@ -72,7 +72,8 @@ describe 'ironic::inspector' do
:ensure => p[:package_ensure],
:tag => ['openstack', 'ironic-inspector-package'],
)
is_expected.to contain_package('ironic-inspector').with_before(/Service\[ironic-inspector\]/)
is_expected.to contain_package('ironic-inspector').that_requires('Anchor[ironic-inspector::install::begin]')
is_expected.to contain_package('ironic-inspector').that_notifies('Anchor[ironic-inspector::install::end]')
end
end
@ -118,10 +119,16 @@ describe 'ironic::inspector' do
is_expected.to contain_ironic_inspector_config('processing/processing_hooks').with_value('$default_processing_hooks')
end
it 'should contain file /etc/ironic-inspector/inspector.conf' do
is_expected.to contain_file('/etc/ironic-inspector/inspector.conf').with(
'ensure' => 'present',
'require' => 'Anchor[ironic-inspector::config::begin]',
)
end
it 'should contain file /etc/ironic-inspector/dnsmasq.conf' do
is_expected.to contain_file('/etc/ironic-inspector/dnsmasq.conf').with(
'ensure' => 'present',
'require' => 'Package[ironic-inspector]',
'require' => 'Anchor[ironic-inspector::config::begin]',
'content' => /pxelinux/,
)
end
@ -131,7 +138,7 @@ describe 'ironic::inspector' do
'group' => 'ironic-inspector',
'seltype' => 'tftpdir_t',
'ensure' => 'present',
'require' => 'Package[ironic-inspector]',
'require' => 'Anchor[ironic-inspector::config::begin]',
'content' => /default/,
)
is_expected.to contain_file('/tftpboot/pxelinux.cfg/default').with_content(
@ -176,7 +183,7 @@ describe 'ironic::inspector' do
it 'should contain file /etc/ironic-inspector/dnsmasq.conf' do
is_expected.to contain_file('/etc/ironic-inspector/dnsmasq.conf').with(
'ensure' => 'present',
'require' => 'Package[ironic-inspector]',
'require' => 'Anchor[ironic-inspector::config::begin]',
'content' => /ipxe/,
)
is_expected.to contain_file('/etc/ironic-inspector/dnsmasq.conf').with_content(
@ -187,9 +194,9 @@ describe 'ironic::inspector' do
is_expected.to contain_file('/var/www/httpboot/inspector.ipxe').with(
'owner' => 'ironic-inspector',
'group' => 'ironic-inspector',
'require' => 'Package[ironic-inspector]',
'seltype' => 'httpd_sys_content_t',
'ensure' => 'present',
'require' => 'Anchor[ironic-inspector::config::begin]',
'content' => /ipxe/,
)
is_expected.to contain_file('/var/www/httpboot/inspector.ipxe').with_content(

View File

@ -23,7 +23,7 @@ describe 'ironic::pxe' do
is_expected.to contain_file('/tftpboot').with(
'owner' => 'ironic',
'group' => 'ironic',
'require' => 'Package[ironic-common]',
'require' => 'Anchor[ironic::config::begin]',
'ensure' => 'directory',
'seltype' => 'tftpdir_t',
)
@ -43,7 +43,7 @@ describe 'ironic::pxe' do
is_expected.to contain_file('/httpboot').with(
'owner' => 'ironic',
'group' => 'ironic',
'require' => 'Package[ironic-common]',
'require' => 'Anchor[ironic::config::begin]',
'ensure' => 'directory',
'seltype' => 'httpd_sys_content_t',
)
@ -67,7 +67,7 @@ describe 'ironic::pxe' do
'flags' => 'IPv4',
'per_source' => '11',
'wait' => 'yes',
'require' => 'Package[tftp-server]',
'subscribe' => 'Anchor[ironic::install::end]',
)
end
@ -84,7 +84,7 @@ describe 'ironic::pxe' do
is_expected.to contain_file('/var/www/httpboot').with(
'owner' => 'ironic',
'group' => 'ironic',
'require' => 'Package[ironic-common]',
'require' => 'Anchor[ironic::config::begin]',
'ensure' => 'directory',
'seltype' => 'httpd_sys_content_t',
)
@ -94,7 +94,7 @@ describe 'ironic::pxe' do
is_expected.to contain_file('/var/lib/tftpboot').with(
'owner' => 'ironic',
'group' => 'ironic',
'require' => 'Package[ironic-common]',
'require' => 'Anchor[ironic::config::begin]',
'ensure' => 'directory',
'seltype' => 'tftpdir_t',
)